namespace cpp

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


anwenden:images

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
anwenden:images [2020-07-26 17:19]
rrichter
anwenden:images [2020-07-26 17:20] (aktuell)
rrichter
Zeile 1: Zeile 1:
 ====== Image : Grafik-Programmierung ohne Grafik-Treiber ====== ====== Image : Grafik-Programmierung ohne Grafik-Treiber ======
- 
-> Du sollst dir kein Bildnis noch irgendein Gleichnis machen, 
-> weder des, das oben im Himmel, 
-> noch des, das unten auf Erden, 
-> oder des, das im Wasser unter der Erde ist. 
->>---  2. Mose 20, 4====== Image : Grafik-Programmierung ohne Grafik-Treiber ====== 
  
 > Du sollst dir kein Bildnis noch irgendein Gleichnis machen, > Du sollst dir kein Bildnis noch irgendein Gleichnis machen,
Zeile 270: Zeile 264:
  
 void print(std::ostream& out, Image const& image) void print(std::ostream& out, Image const& image)
-{ 
-  out << "\n\nRGB-Alpha-Bild " 
-      << image.width() << " x " << image.height() << '\n'; 
- 
-  for (unsigned y = 0; y < image.height(); ++y) 
-  { 
-    for (unsigned x = 0; x < image.width(); ++x) 
-    { 
-      out << std::setw(9) << std::hex << image.pixel(x,y); 
-    } 
-    out << '\n'; 
-  } 
-} 
- 
-int main() 
-{ 
-  Color c(255, 0, 0, 127); // red, 50% transparency 
-  Image image(100, 75); 
- 
-  for (unsigned x = 0; x < image.height(); ++x) 
-  { 
-    image.pixel(x, x) = c;                             // rising line 
-    image.pixel(x, image.height()/ ) = Color::BLUE;  // mid horizon line 
-    image.pixel(x, image.height()-1-x) = Color::GREEN; // falling line 
-  } 
-  image.pixel(-1, 1) = Color::WHITE; // outside ignored, doesn't crash! 
- 
-  std::ofstream file("image.dat"); 
-  print(file, image); 
-  saveBMP("image24.bmp", image); 
- 
-  return 0; 
-} 
-//~ 
-</code> 
-Das Testprogramm erzeugt eine Bilddatei mit 
- 
- 
-  * aufsteigender roter Linie 
-  * waagerechter blauer Linie und 
-  * fallender grüner Linie: 
- 
-{{anwenden:image24.png|}} 
- 
-Weitergehende Übungen führen in verschiedene Richtungen: 
- 
- 
-  * 2D-Grafik (Linien, Balken, Polygone, Kurven, Farbverläufe), 
-  * Bildbearbeitung (Überlagern, Ausschneiden, Bildeffekte), 
-  * 3D-Grafik (Projektion, Verdeckungsrechnung, Beleuchtungsgeometrie), 
-  * Simulation und Visualisierung (2D, 3D), 
-  * Bild-Datei-Konversion (Kompressionsalgorithmen). 
-Viel Spaß! 
- 
- 
- 
- 
-Wir verstoßen ständig gegen das zweite Gebot.  
-Schlachten wir eine weitere heilige Kuh: 
-"Grafikprogrammierung ist nichts für Anfänger. 
-Dazu braucht man schnelle Rechner, 
-teure Grafikkarten und Programmierbibliotheken 
-mit hohem Einarbeitungsaufwand (OpenGL, DirectX, SDL, ...)." 
-Nichts da. Es geht nicht um 3D-Ego-Shooter. 
-Es geht nicht um: 
-"Mein Grafikprozessorkühler ist 2 cm länger als deiner." 
-Servergenerierte Aktiencharts brauchen keine Framerate. 
- 
-Vor dem Jahr 1990 habe ich 9-Nadel-Drucker punktweise angesteuert 
-im Epson-Escape(P)-Befehlssatz, 
-weil ich computerberechnete Ergebnisse in Bildform ausdrucken wollte. 
-Grafikkarte jenseits von Basic-Kleincomputern? Fehlanzeige. 
-Man braucht einen geordneten Zugriff auf Bildpunktdaten im Hauptspeicher 
-und einen Speicher, auf dem Bilder abzulegen sind. Alles weitere ist Routine. 
-Und es gibt eine Menge dabei zu lernen. 
-Willkommen im Bereich der Retroprogrammierung. 
- 
-===== Aufgabe ===== 
-Erstelle die Grundlagen der Computergrafik. 
-Gehe in folgenden Schritten vor: 
- 
- 
-  - Definiere 32-Bit-Farben (je 8 Bit für rot, grün, blau, Transparenz). 
-  - Bilder beliebiger Größe sind als Klasse zu vereinbaren. 
-  - Speichere das Bild als Datei (z.B. BMP, einfaches Datenformat). 
-Der Zugriff auf die Farben einzelner Bildpunkte soll einfach und robust sein. 
- 
-===== Lösung ===== 
- 
- 
- 
-==== Klasse Color ==== 
-Die vier Farbinformationen werden in einer Klasse gebündelt. 
- 
-<code cpp color.h> 
-//: color.h : Grafik-Bibliothek ohne Grafiktreiber - R.Richter 2011-01-15 
-///////////////////////////////////////////////////////////////////////// 
- 
-#ifndef COLOR_H 
-#define COLOR_H 
- 
-// Farben, 24 bit Farbtiefe mit Transparenz (Alpha-Kanal) 
- 
-class Color 
-{ 
-public: 
-  typedef unsigned char Channel; 
-  typedef unsigned long RGBAlpha; 
- 
-  enum  
-  { 
-    NONE   = 0xFF000000, 
-    BLACK  = 0x00000000, 
-    WHITE  = 0x00FFFFFF, 
-    RED    = 0x00FF0000, 
-    GREEN  = 0x0000FF00, 
-    BLUE   = 0x000000FF, 
-    YELLOW = 0x00FFFF00 
-  }; 
- 
-  Color(Channel red, Channel green, Channel blue, Channel alpha = 0) 
-  : value( rgba(red, green, blue, alpha ) ) 
-  { 
-  } 
- 
-  Color(RGBAlpha color = 0xff000000) // default: transparent 
-  : value(color) 
-  { 
-  } 
- 
-  Channel alpha() const { return Channel(value>>24); } 
-  Channel red()   const { return Channel(value>>16); } 
-  Channel green() const { return Channel(value>>8);  } 
-  Channel blue()  const { return Channel(value);     } 
- 
-  operator unsigned long() const { return value; } 
-private: 
-  RGBAlpha value; 
- 
-  static RGBAlpha rgba(Channel red, Channel green, Channel blue, Channel alpha) 
-  { 
-    return   RGBAlpha(alpha)<<24 | RGBAlpha(red)<<16 
-    | RGBAlpha(green)<< | RGBAlpha(blue); 
-  } 
-}; 
- 
-#endif // COLOR_H 
-//~ 
-</code> 
-Intern werden die Daten zu einer Langzahl zusammengefasst. 
-Für den einfachen Umgang werden einige Standardfarben festgelegt. 
-Die Farbklasse ist unvollständig: 
- 
- 
-  * Welche weiteren Farben sind als Standardfarben zu definieren? 
-  * Welche Rechengesetze gelten für Farben ? 
- 
- 
- 
- 
-==== Klasse Image ==== 
-Ein Bild hat eine bestimmte Breite und eine bestimmte Länge, 
-die nachfolgend nicht mehr änderbar ist. 
-Solange noch kein Bildpunkt bemalt wurde, ist das Bild durchsichtig, 
-es sei denn, eine Hintergrundfarbe wurde festgelegt. 
-Einzelne Bildpunkte können als ''pixel(x,y)'' abgefragt  
-und auf eine neue Farbe gesetzt werden. 
-Der Zugriff auf Punkte außerhalb des Bildes bleibt folgenlos. 
- 
-<code cpp image.h> 
-//: image.h : Grafik-Bibliothek ohne Grafiktreiber - R.Richter 2011-01-15 
-///////////////////////////////////////////////////////////////////////// 
- 
-#ifndef IMAGE_H 
-#define IMAGE_H 
- 
-#include <algorithm> 
-#include <vector> 
-#include "color.h" 
- 
-class Image 
-{ 
-public: 
-  Image(unsigned int width, unsigned int height, Color background = 0) 
-  : width_(width), height_(height), pixels_(width * height, background) 
-  { 
-  } 
- 
-  unsigned int width()  const { return width_;  } 
-  unsigned int height() const { return height_; } 
- 
-  Color& pixel(unsigned int x, unsigned int y)  
-  { 
-    return x>=width() || y>=height() ? outside() : pixels_[y*width() + x]; 
-  } 
-   
-  const Color& pixel(unsigned int x, unsigned int y) const  
-  { 
-    return x>=width() || y>=height() ? outside() : pixels_[y*width() + x]; 
-  } 
-private: 
-  unsigned int width_, height_; 
-  std::vector<Color> pixels_; // width_ x height_ pixels 
- 
-  static Color& outside() { static Color c; return c = Color::NONE; } 
-}; 
- 
-// ===[ Speichern als BMP 24bit unkomprimiert, ohne Transparenz ]=========== 
- 
-#include <fstream> 
-#include <iostream> 
-#include <iomanip> 
-#include <string> 
- 
-// Achtung, nicht portabel: Intel Byte-order vorausgesetzt 
- 
-inline  // a bit too long for ... 
-void saveBMP(std::string filename, const Image& image) 
-{ 
-  const unsigned long linesize  = 3*image.width();  // 24 bit per pixel 
-  const unsigned long fillbytes = (4-linesize%4)%4; // at end of line to quad boundary 
-  const unsigned long imagesize = (linesize+fillbytes)*image.height(); 
- 
-  // byte alignment, no padding 
-  // #if defined( _MSC_VER ) || defined( __MINGW32__ ) 
-  #pragma pack(1) 
-  // #endif 
-  struct BMPheader 
-  { 
-    // file info 
-    char ID[2]; 
-    unsigned long filesize, reserved, offset; 
- 
-    // BMP info 
-    unsigned long  infosize, width, height; 
-    unsigned short planes, bitsperpixel; 
-    unsigned long  compression, imagesize, 
-                   xPixelPerMeter, yPixelPerMeter, 
-                   colorsUsed, colorsImportant; 
-  } header = 
-  {  
-    // file info 
-    { 'B', 'M' }, 
-    unsigned(sizeof(header)) + imagesize, // 24 bits per pixel 
-    0, sizeof(header),          // 0x36 
- 
-    // BMP info 
-    40, image.width(), image.height(), 
-    1, 24, 
-    0, imagesize, 
-    1000, 1000, 
-    0, 0 
-  }; 
-  // #if defined( _MSC_VER ) || defined( __MINGW32__ ) 
-  #pragma pack() 
-  // #endif 
- 
-  std::ofstream file(filename.c_str(), std::ios::out|std::ios::binary); 
-  file.write( (char*)&header, sizeof(header)); // Intel byte order 
- 
-  for (unsigned y = 0; y < image.height(); ++y) 
-  { 
-    for (unsigned x = 0; x < image.width(); ++x) 
-    { 
-      Color c= image.pixel(x,y); 
-      unsigned char b = c.blue(), g = c.green(), r = c.red(); 
-      file.write( (char*) &b, 1); 
-      file.write( (char*) &g, 1); 
-      file.write( (char*) &r, 1); 
-    } 
-    if (fillbytes) 
-    { 
-      int zero = 0; 
-      file.write( (char*) &zero, fillbytes); 
-    } 
-  } 
-} 
- 
-#endif // IMAGE_H 
-//~ 
-</code> 
- 
- 
- 
-===== Dateiformat ===== 
-Das BMP-Format wurde hier gewählt, weil es  
-einen relativ einfachen Aufbau hat (ohne Kompression) und 
-24-Bit-Farben erlaubt. Jedoch geht die Transparenz-Infornation verloren. 
-Für das PNG-Format (mit Transparenz) gibt es einen  
-[[http://members.gamedev.net/lode/projects/LodePNG/|quelloffenen Code]], 
-welcher die Bytefolge ABGR statt   
-der in SDL, HTML und hier verwendeten Folge (A)RGB benutzt. 
-Andere Dateiformate (Targa, GIF, JPEG, ...) 
-sind weitergehende Übungsaufgaben. Quellen: Günter Born, Dateiformate. 
- 
- 
- 
- 
-===== Testprogramm ===== 
-Das Hauptprogramm zeigt, wie einfach der Umgang mit Bildern ist. 
-Der Inhalt eines Bildes kann als Zahlenkolonne (plain text) 
-oder als Bitmap-Datei gespeichert werden: 
- 
-<code cpp grafik.cpp> 
-//: grafik.cpp : Grafik-Bibliothek ohne Grafiktreiber - R.Richter 2011-01-15 
-//////////////////////////////////////////////////////////////////////////// 
- 
-#include <fstream> 
-#include <iostream> 
-#include <iomanip> 
-#include "image.h" 
- 
-void print(std::ostream& out, const Image& image) 
 { {
   out << "\n\nRGB-Alpha-Bild "   out << "\n\nRGB-Alpha-Bild "
anwenden/images.txt · Zuletzt geändert: 2020-07-26 17:20 von rrichter