Bilder öffnen
-
Wie der Titel sagt, brauche ich eine Möglichkeit, um Bilder zu öffnen. Ich will dann in C++ jedes einzelne Pixel bearbeiten können.
Ich bin mir nicht ganz sicher, mit welchem Format das am Einfachsten geht, es sollte nur ein gängiges Format sein, dass sich für sich reale Bilder eignet.(also für Bilder wie sie z.B. von der Digicam kommen).
Ich benutze den Dev-C++ unter Windows.
Zarniwoop
PS: Korigiert mich, wenn ich im falschen Bereich gepostet hab, war mir nicht sicher wo das hinsoll.
-
a) du oeffnest die Datei mit den normalen C++ Moeglichkeiten (fstream) und liest die Datei einfach aus. Bei normalen Bitmaps (.bmp) sollte das eine brauchbare Moeglichkeit sein. Bei komplizierteren Dateiformaten (JPG, PNG, etc.) wirds wohl nix
b) du nimmst spezielle Libraries, die fuer ein Dateiformat zugeschnitten sind (z. B. kannst du mit der libpng PNG-Dateien bearbeiten)
c) du nimmst Multimedia-Libraries, die einzelne Dateiformate abstrahieren. z. B. gibt es fuer die SDL (www.libsdl.org) die Zusatzlib "SDL_image", mit der du viele bekannte Dateiformate oeffnen kannst. Ueber SDL selber koenntest du dann die Bilder bearbeiten.
d) du nimmst GUI-Libraries, z. B. wxWidgets oder auch nur die WinAPI.
was genau soll dein Programm den koennen/wie soll es denn aussehen?
-
also für Bilder wie sie z.B. von der Digicam kommen).
hier code wie man ein bmp file mit 24 bit farbtiefe (unkomprimiert) öffnet - funzt auf win und linux:
// 24 bit pixel grid typedef struct { unsigned char r; unsigned char g; unsigned char b; } Pixel; typedef struct { int width; int heigth; Pixel *Pixel; } PixelGrid; // PixelGrid *newPixelGrid(char *Filename); // constructor -does only support uncompresed 24 bit bitmap graphics typedef struct { unsigned short int type; // Magic identifier unsigned int size; // File size in bytes unsigned short int reserved1, reserved2; unsigned int offset; // Offset to image data, bytes } HEADER; typedef struct { unsigned int size; // Header size in bytes int width,height; // Width and height of image unsigned short int planes; // Number of colour planes unsigned short int bits; // Bits per pixel unsigned int compression; // Compression type unsigned int imagesize; // Image size in bytes int xresolution,yresolution; // Pixels per meter unsigned int ncolours; // Number of colours unsigned int importantcolours; // Important colours } INFOHEADER; typedef struct { unsigned char b; unsigned char g; unsigned char r; } PIXEL; PixelGrid *newPixelGrid(char *Filename) { long offset = 0L; int extra_bytes_per_line = 0; int lineNumber = 0; int numElement = 0; FILE *ptrFile = NULL; HEADER Header; INFOHEADER InfoHeader; PixelGrid *newPixelGrid = NULL; PIXEL bmpPixel; int infosize = 0; // Size of header information // try opening the file; use "rb" mode to read this *binary* file if(!(ptrFile = fopen(Filename, "rb"))) return NULL; // read header Header.type = (unsigned short int)getFileInfo(ptrFile, 0L, 2); Header.size = (unsigned int)getFileInfo(ptrFile, 2L, 4); Header.reserved1 = (unsigned short int)getFileInfo(ptrFile, 6L, 2); Header.reserved2 = (unsigned short int)getFileInfo(ptrFile, 8L, 2); Header.offset = (unsigned short int)getFileInfo(ptrFile, 10L, 4); // print header printf("type: %d\n", Header.type); printf("size: %d\n", Header.size); printf("reserved1: %d\n", Header.reserved1); printf("reserved2: %d\n", Header.reserved2); printf("offset: %d\n", Header.offset); // read info header InfoHeader.size = (unsigned int)getFileInfo(ptrFile, 14L, 4); InfoHeader.width = (int)getFileInfo(ptrFile, 18L, 4); InfoHeader.height = (int)getFileInfo(ptrFile, 22L, 4); InfoHeader.planes = (unsigned short int)getFileInfo(ptrFile, 26L, 2); InfoHeader.bits = (unsigned short int)getFileInfo(ptrFile, 28L, 2); InfoHeader.compression = (unsigned int)getFileInfo(ptrFile, 30L, 4); InfoHeader.imagesize = (unsigned int)getFileInfo(ptrFile, 34L, 4); InfoHeader.xresolution = (int)getFileInfo(ptrFile, 38L, 4); InfoHeader.yresolution = (int)getFileInfo(ptrFile, 42L, 4); InfoHeader.ncolours = (unsigned int)getFileInfo(ptrFile, 46L, 4); InfoHeader.importantcolours = (unsigned int)getFileInfo(ptrFile, 40L, 4); // print info header printf("size: %d\n", InfoHeader.size); printf("width: %d\n", InfoHeader.width); printf("height: %d\n", InfoHeader.height); printf("planes: %d\n", InfoHeader.planes); printf("bits: %d\n", InfoHeader.bits); printf("compression: %d\n", InfoHeader.compression); printf("imagesize: %d\n", InfoHeader.imagesize); printf("xresolution: %d\n", InfoHeader.xresolution); printf("yresolution: %d\n", InfoHeader.yresolution); printf("ncolors: %d\n", InfoHeader.ncolours); printf("importantcolours: %d\n", InfoHeader.importantcolours); // check file if(Header.type != 'MB') { // Not a bitmap file - return NULL... fclose(ptrFile); return NULL; } if(InfoHeader.bits != 24u) { printf("wrong bitmap format - only a bit depth of 24 bit is supportetd!\n"); return NULL; } newPixelGrid = malloc(sizeof(PixelGrid)); newPixelGrid->width = InfoHeader.width; newPixelGrid->heigth = InfoHeader.height; newPixelGrid->Pixel = malloc(sizeof(Pixel) * InfoHeader.width * InfoHeader.height); if(newPixelGrid->Pixel == NULL) printf("malloc failed"); // here comes the tricky part // // bmp file looks something like this: // ------------------------ // |(0|9)| ... |(9|9)| // | | // | ... ... | // | | // |(0|0)| ... |(9|0)| // ------------------------ // PixelGrid uses following convention: // ------------------------ // |(0|0)| ... |(9|0)| // | | // | ... ... | // | | // |(0|9)| ... |(9|9)| // ------------------------ // als b g r must be convertet to r g b extra_bytes_per_line = (4-((InfoHeader.width * 3)%4))%4; offset = 54L; for(lineNumber = InfoHeader.height-1; lineNumber >= 0; lineNumber--) { for(numElement = 0; numElement < InfoHeader.width ; numElement++) { //printf("%d\n", lineNumber * InfoHeader.width + numElement); newPixelGrid->Pixel[lineNumber * InfoHeader.width + numElement].b = (unsigned char)getFileInfo(ptrFile, offset, 1); offset += 1; newPixelGrid->Pixel[lineNumber * InfoHeader.width + numElement].g = (unsigned char)getFileInfo(ptrFile, offset, 1); offset += 1; newPixelGrid->Pixel[lineNumber * InfoHeader.width + numElement].r = (unsigned char)getFileInfo(ptrFile, offset, 1); offset += 1; } offset = offset + (long)extra_bytes_per_line; } // OK, everything went fine - return the allocated bitmap... fclose(ptrFile); return newPixelGrid; }
-
@ blue-Tiger:
Das Ganze ist ein Kunstprojekt für die Schule, mit dem ich meine bescheidenen Malkünste etwas auszugleichen hoffe. Das Programm soll also ein Bild öffnen und nach bestimmten Vorgeben verändern und dann am Besten auch wieder als nues Bild speichern. Eine Art Filter also.
Was du gepostet hast, sieht ganz gut aus. Ich werds auch gleich mal ausprobieren wenn ich Zeit hab. Gut ist auch, dass es Plattformunabhängig ist. JPEGs wie sie (normalerweise) von Digicams gelifert werden muss ich halt vorher umwandeln.
Danke an beide für die Hilfe!
Zarniwoop
-
Hab jetzt doch ein paar Probleme mit dem Code:
Es gibt sowohl die Struktur Pixel als auch eine Instanz der Struktur Pixel, die Pixel heißt. Hab die Struktur jetzt einfach mal in Pixelstruct umbenannt un an den entsprechenden Stellen den Namen geändert.
Wo kriege ich die Funktion GetFileInfo() her?
Außerdem meldet Dev-C++ noch: "invalid conversion form *void to Pixelstruct*" in der Zeile in der steht:
newPixelGrid->Pixel = malloc(sizeof(Pixelstruct) * InfoHeader.width * InfoHeader.height);
Das war ne Zeile drüber auch, aber konnte ich das Problem beseitigen indem ich new statt malloc verwendet hab.
Wie beseitige ich diese Probleme?
Zarniwoop
-
http://openil.sourceforge.net/
http://www.imagemagick.org/Magick++/Außerdem meldet Dev-C++ noch: "invalid conversion form *void to Pixelstruct*" in der Zeile in der steht:
newPixelGrid->Pixel = malloc(sizeof(Pixelstruct) * InfoHeader.width * InfoHeader.height);
du versuchst C Code mit einem C++ Compiler zu kompilieren. C++ hat nämlich keinen implizieten void*-Cast mehr. Daher musst du den Rückgabewert entweder casten oder new benutzen.
-
Ich dachte immer, C ist eine Untermenge von C++ und C++ hat alles, was C auch hat.
Dann schau ich mir mal die beiden Links an die du gepostet hast.
Zarniwoop
-
Zarniwoop schrieb:
Ich dachte immer, C ist eine Untermenge von C++ und C++ hat alles, was C auch hat.
Das stimmt nur begrenzt. Es gibt ein paar Änderungen an der C Untermenge.
-
hier eine funktionierende Version:
http://turing.fh-landshut.de/~jamann/AlphaBlender.c
hier steht was das programm macht:
http://turing.fh-landshut.de/~jamann/AlphaBlender - Softwaredesign Dokument.pdfsollte man einfach ändern können