[gelöst] einfachster weg von std::vector zu bild auf der festplatte



  • @Nexus
    naja dann hast du das bildtyp danach halt überlesen.

    weißt du denn was ich in meinem vector gespeichert habe? ansonsten kannst du wohl die sinnhaftigkeit der operation nur schwer einschätzen. zugegeben meine beschreibung des problems hätte präziser sein können.

    ist aber wirklich kein grund gleich so ausfallend zu werden.
    das rad immer neu zu erfinden ist nicht notwendig und ich will hier halt nicht allzu viel arbeit investieren.

    @Kóyaánasqatsi
    danke, dann werde ich mich wohl doch damit beschäftigen müssen.

    @SeppJ
    der zweidimensionale vektor enthält die pixelwerte des bildes.

    jperl



  • jperl schrieb:

    ist aber wirklich kein grund gleich so ausfallend zu werden.
    das rad immer neu zu erfinden ist nicht notwendig und ich will hier halt nicht allzu viel arbeit investieren.

    Bin ich ausfallend geworden? Ich habe nur den Sinn in Frage gestellt. Es ist nun mal so, dass Standard-C++ keine Möglichkeit zur Bildbearbeitung bietet, also musst du dich mit externen Bibliotheken befassen. Und ob das nun die WinAPI, SFML oder sonst irgendwas ist, etwas Einarbeitungszeit brauchst du so oder so.



  • Nexus schrieb:

    jperl schrieb:

    ist aber wirklich kein grund gleich so ausfallend zu werden.
    das rad immer neu zu erfinden ist nicht notwendig und ich will hier halt nicht allzu viel arbeit investieren.

    Bin ich ausfallend geworden? Ich habe nur den Sinn in Frage gestellt. Es ist nun mal so, dass Standard-C++ keine Möglichkeit zur Bildbearbeitung bietet, also musst du dich mit externen Bibliotheken befassen. Und ob das nun die WinAPI, SFML oder sonst irgendwas ist, etwas Einarbeitungszeit brauchst du so oder so.

    das nehme ich hiermit zur kenntnis.

    das hättest du auch gleich schreiben können, ohne meine arbeitsmoral oder mein vorgehen anzuzweifeln.

    jperl



  • Ich fand libpng ganz nett. Da gibts auch ein schönes C++ Header-File dazu. Allerdings müsstest Du den Inhalt des Vectors irgendwie in ein png::image<pixel_type> umwandeln und dann das Bild mit .write() in eine Datei schreiben.

    Sonst gibt es noch recht billige Dateiformate, wie zB TGA. Das ist -- wenn ich mich richtig erinnere -- ein relativ einfacher 18byte-Header gefolgt von Rohdaten. -- Zum eben mal Testen / Reinhacken sollte das gehen.



  • Was du hier willst, ist dass dir jemand Code postet der dich vom std::vector zum Bild führt und du somit dir die Arbeit sparst. Ich kann aber nachvollziehen, dass die wenigsten dazu Lust haben.



  • Sebastian Pizer schrieb:

    Ich fand libpng ganz nett. Da gibts auch ein schönes C++ Header-File dazu. Allerdings müsstest Du den Inhalt des Vectors irgendwie in ein png::image<pixel_type> umwandeln und dann das Bild mit .write() in eine Datei schreiben.

    Sonst gibt es noch recht billige Dateiformate, wie zB TGA. Das ist -- wenn ich mich richtig erinnere -- ein relativ einfacher 18byte-Header gefolgt von Rohdaten. -- Zum eben mal Testen / Reinhacken sollte das gehen.

    danke. werde ich mir mal ansehen.

    wer einen umkomplizierten weg sucht und octave/matlab installiert hat, der soll einfach die daten im csv format auf die festplatte schreiben, diese dann dort einlesen und mit imshow anzeigen.
    ist aber nur eine sehr eingeschränkte lösung deswegen werde ich mir mal eine lib einverleiben.

    jperl



  • Richtige stl-mäßige Bildbearbeitung gibt es in boost:

    http://www.boost.org/doc/libs/1_40_0/libs/gil/doc/index.html



  • It0101 schrieb:

    Was du hier willst, ist dass dir jemand Code postet der dich vom std::vector zum Bild führt und du somit dir die Arbeit sparst. Ich kann aber nachvollziehen, dass die wenigsten dazu Lust haben.

    ich kenne ja das phänomen je besser man sich in einem thema auskennt, desto unfreundlicher wird man. aber trotzdem würde ich gerne zum konstruktiven teil, dieses threads zurückkommen.

    jperl



  • Sebastian und nn haben dir zwei gute Lösungen vorgestellt. Damit ist der konstruktive Teil doch abgehakt und deine Frage beantwortet.



  • jperl schrieb:

    das hättest du auch gleich schreiben können, ohne meine arbeitsmoral oder mein vorgehen anzuzweifeln.

    jperl schrieb:

    ich kenne ja das phänomen je besser man sich in einem thema auskennt, desto unfreundlicher wird man. aber trotzdem würde ich gerne zum konstruktiven teil, dieses threads zurückkommen.

    Ich habe irgendwie das Gefühl, du bist etwas sensibel und kannst nicht so richtig mit Kritik an deiner Vorgehensweise (ohne Aufwand viel erreichen) umgehen. Dass du unsere Sätze als "unfreundlich" und "ausfallend" bezeichnest... Naja.



  • It0101 schrieb:

    Sebastian und nn haben dir zwei gute Lösungen vorgestellt. Damit ist der konstruktive Teil doch abgehakt und deine Frage beantwortet.

    meine frage ist auch beantwortet.
    deswegen war dein post auch überflüssig.

    jperl

    #edit
    mag sein dass ich ein wenig sensibel bin. eure statements waren meiner meinung nach einfach nicht gerechtfertigt und auch nicht notwendig.



  • jperl schrieb:

    #edit
    mag sein dass ich ein wenig sensibel bin. eure statements waren meiner meinung nach einfach nicht gerechtfertigt und auch nicht notwendig.

    sensibel stimmt. versetz dich mal in die Lage der Leute hier. dein erster und zweiter Post lesen sich zusammengefasst etwa wie "ich will ein Bild, will mich aber nicht mit Bildformaten beschäftigen", was wiederum an die leider viel zu häufige Haltung "gebt mir mal schnell meinen Code, ich hab keinen Bock den selber zu machen" erinnert.
    Hier im Forum ists wie überall im Netz: Wenn sich deiner Meinung nach jemand ein wenig im Ton vergreift bringt es meistens nichts, sich drüber aufzuregen. Den Tonfall einfach ausblenden und dir die Infos rausziehen die du brauchst 🙂



  • pumuckl schrieb:

    jperl schrieb:

    #edit
    mag sein dass ich ein wenig sensibel bin. eure statements waren meiner meinung nach einfach nicht gerechtfertigt und auch nicht notwendig.

    sensibel stimmt. versetz dich mal in die Lage der Leute hier. dein erster und zweiter Post lesen sich zusammengefasst etwa wie "ich will ein Bild, will mich aber nicht mit Bildformaten beschäftigen", was wiederum an die leider viel zu häufige Haltung "gebt mir mal schnell meinen Code, ich hab keinen Bock den selber zu machen" erinnert.
    Hier im Forum ists wie überall im Netz: Wenn sich deiner Meinung nach jemand ein wenig im Ton vergreift bringt es meistens nichts, sich drüber aufzuregen. Den Tonfall einfach ausblenden und dir die Infos rausziehen die du brauchst 🙂

    ich war wohl heute auch nicht allzu gut drauf, deshalb habe ich das wohl ein wenig persönlich genommen.

    folgendes problem:
    irgendwo scheint ein fehler zu sein. ich will mir ein 2x2 bild erzeugen gleich dem wie der header hier angegeben ist:
    http://en.wikipedia.org/wiki/BMP_file_format#Example_of_a_2x2_Pixel.2C_24-Bit_Bitmap

    meine daten betrachte ich einfach als grauwerte, also schreibe ich in alle 3 byte den gleichen wert. im moment sind die pixelwerte noch mit null initialisiert.

    meine erzeugte datei in hex sieht so aus:
    42 4d 00 00 46 00 00 00 00 00 00 00 36 00 00 00 28 00 00 00 02 00 00 00 02 00 00 00 01 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    aussehen sollte sie so (ist getestet, diese datei kann ich öffnen):
    42 4d 46 00 00 00 00 00 00 00 36 00 00 00 28 00 00 00 02 00 00 00 02 00 00 00 01 00 18 00 00 00 00 00 10 00 00 00 13 0b 00 00 13 0b 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 ff 00 00 00 ff 00 00 00

    sieht jemand den fehler. 😕

    #include <vector>
    #include <string>
    
    typedef struct {
    	 char id[2]; //magic number
    	 unsigned long filesize; //size of the file
    	 unsigned short reserved[2]; //unused
    	 unsigned long headersize; //the offset where the bitmap data (pixels) can be found
    	 unsigned long infoSize; //the number of bytes in the header (from this point)
    	 unsigned long width; //width of image
    	 unsigned long height; //height of the image
    	 unsigned short biPlanes; //number of color planes
    	 unsigned short bits; //number of bits/pixel
    	 unsigned long biCompression; //if compression is used
    	 unsigned long biSizeImage; //size of raw BMP data
    	 unsigned long biXPelsPerMeter; //horizontal resolution
    	 unsigned long biYPelsPerMeter; //vertical resolution
    	 unsigned long biClrUsed; //number of colors in the palette
    	 unsigned long biClrImportant; //importance of colors
    } BMPHEAD;
    
    void vec2bmp(std::vector< std::vector< char > > &v, std::string filename)
    {
    	BMPHEAD bh;
    
    	memset((char *)&bh, 0, sizeof(BMPHEAD));
    	memcpy(bh.id, "BM", 2);
    	bh.headersize = 54;  
    	bh.infoSize = 40; 
    	bh.height = static_cast<long>(v.size());
    	bh.width = static_cast<long>(v[0].size());
    	bh.biPlanes =  1; //1 color plane
    	bh.bits = 24; //24bit
    	bh.biCompression = 0L; //no compression
    
    	int bytesPerLine;
    
    	bytesPerLine = bh.width * 3;
    	/* round up to bytesPerLine % 4 == 0 */
    	if (bytesPerLine & 0x0003) 
    	{
    		bytesPerLine |= 0x0003;
    		++bytesPerLine;
    	}
    
    	bh.filesize = bh.headersize + (long)bytesPerLine * bh.height;
    
    	FILE * bmpfile;
    	bmpfile = fopen(filename.c_str(), "wb");
    	if (bmpfile == NULL)
    	{
    	   printf("Error opening output file\n");
    	   std::exit(1);
    	}
    	fwrite(&bh, 1, sizeof (bh), bmpfile);
    
    	//buffer for one line
    	char *linebuf;
    
    	linebuf = new char[bytesPerLine];
    	for(int i = 0; i < bytesPerLine; ++i)
    		linebuf[i] = 0;
    
    	int line;
    	for (line = bh.height - 1; line >= 0; line--)
    	{
    	   /* fill line linebuf with the image data for that line */
    		for(int col = 0; col < bh.width; ++col)
    		{
    			//std::cout << line << " " << col << std::endl;
    			int sI = col*3;
    			linebuf[sI] = v[line][col];
    			linebuf[++sI] = v[line][col];
    			linebuf[++sI] = v[line][col];
    		}
    
    		fwrite(linebuf, 1, bytesPerLine, bmpfile);
    	}
    
    	fclose(bmpfile);
    };
    

    der aufruf sieht wie folgt aus:

    std::vector< std::vector < char > > v(2, std::vector< char >(2, 0));
    vec2bmp(v, "test.bmp");
    

    jperl



  • wird vermutlich am structure packing liegen.

    #pragma pack(push)
    #pragma pack(1)
    
    typedef struct {
         char id[2]; //magic number
         unsigned long filesize; //size of the file
         unsigned short reserved[2]; //unused
         unsigned long headersize; //the offset where the bitmap data (pixels) can be found
         unsigned long infoSize; //the number of bytes in the header (from this point)
         unsigned long width; //width of image
         unsigned long height; //height of the image
         unsigned short biPlanes; //number of color planes
         unsigned short bits; //number of bits/pixel
         unsigned long biCompression; //if compression is used
         unsigned long biSizeImage; //size of raw BMP data
         unsigned long biXPelsPerMeter; //horizontal resolution
         unsigned long biYPelsPerMeter; //vertical resolution
         unsigned long biClrUsed; //number of colors in the palette
         unsigned long biClrImportant; //importance of colors
    } BMPHEAD;
    
    #pragma pack(pop)
    
    // ...
    


  • hustbaer schrieb:

    wird vermutlich am structure packing liegen.

    #pragma pack(push)
    #pragma pack(1)
    
    typedef struct {
         char id[2]; //magic number
         unsigned long filesize; //size of the file
         unsigned short reserved[2]; //unused
         unsigned long headersize; //the offset where the bitmap data (pixels) can be found
         unsigned long infoSize; //the number of bytes in the header (from this point)
         unsigned long width; //width of image
         unsigned long height; //height of the image
         unsigned short biPlanes; //number of color planes
         unsigned short bits; //number of bits/pixel
         unsigned long biCompression; //if compression is used
         unsigned long biSizeImage; //size of raw BMP data
         unsigned long biXPelsPerMeter; //horizontal resolution
         unsigned long biYPelsPerMeter; //vertical resolution
         unsigned long biClrUsed; //number of colors in the palette
         unsigned long biClrImportant; //importance of colors
    } BMPHEAD;
    
    #pragma pack(pop)
    
    // ...
    

    genau daran lag es. vielen dank.
    daran hatte ich gar nicht gedacht.

    jperl



  • nächstes mal einfach die vordefinierten structs aus den windows-headers verwenden, dann musst du dich darum nicht kümmern.



  • hustbaer schrieb:

    nächstes mal einfach die vordefinierten structs aus den windows-headers verwenden, dann musst du dich darum nicht kümmern.

    davon gibt es aber kein entsprechendes pendant für linux oder?

    jperl

    achja zur info:
    hätte hier jetzt eine einfache klasse gefunden die ich eigentlich gesucht hätte.
    hab aber nur kurz drübergeschaut, da ich jetzt ja meine eigene routine habe.
    scheint ganz ok zu sein:
    http://www.kalytta.com/bitmap.h


Anmelden zum Antworten