Seite 1 von 1

QImage 8bit abspeichern

Verfasst: 16. August 2009 19:14
von Treehouse
Hallo,

ich versuche gerade Pixel in einem 8Bit QImage Objekt, zu manipulieren.
Dabei habe ich das Problem das die Pixel nicht manipuliert werden und beim abspeichern ein "Segmention fault" Fehler auftritt. Nun frage ich mich woran das liegt. Hier mal der code

Code: Alles auswählen

QVector<QRgb> vcolorTable;
		QRgb *colorTable = new QRgb[256];
		m_Image = QImage(400, 400, QImage::Format_Indexed8);
		
		for (int i = 0; i < 256; i++) {
			colorTable[i] = qRgb(i, i, i);
			vcolorTable[i] = colorTable[i];
		}
	
		m_Image.setColorTable(vcolorTable);
		
		for (int j=0; j < 200; j++)
			for ( int i=0; i < 400; i++)
				*(m_Image.scanLine(j) + i)  = (uchar) 0;
		
		m_Image.save("bild.bmp");
Kann mir vielleicht jemand von euch sagen woran das liegt?

Gruß

Treehouse

Verfasst: 16. August 2009 19:40
von franzf
Du hast das warning zu scanline gelesen?
Warning: If you are accessing 32-bpp image data, cast the returned pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the pixel value. You cannot use the uchar* pointer directly, because the pixel format depends on the byte order on the underlying platform. Use qRed(), qGreen(), qBlue(), and qAlpha() to access the pixels.
Damit ist es klar dass diese Zeile

Code: Alles auswählen

*(m_Image.scanLine(j) + i)  = (uchar) 0;
nur Probleme bereiten kann.
Warum verwendest du denn nicht einfach setPixel?
Und setColorTable hast du auch geschaut?
When the image is used, the color table must be large enough to have entries for all the pixel/index values present in the image, otherwise the results are undefined.
Und das hier

Code: Alles auswählen

for (int i = 0; i < 256; i++) { 
         colorTable[i] = qRgb(i, i, i); 
         vcolorTable[i] = colorTable[i]; 
      } 
ist doch überflüssig, oder? Häng doch das QRgb direkt an vcolorTable an.

Verfasst: 17. August 2009 09:55
von androphinx
und warum nimmst du nicht die funktion pixel() ??? die ist einfacher und sicherer, was solche fehler anbelangt...

Mfg androphinx

Re: QImage 8bit abspeichern

Verfasst: 17. August 2009 13:21
von Curtis Newton

Code: Alles auswählen

QVector<QRgb> vcolorTable;
		m_Image.setColorTable(vcolorTable);
vcolorTable ist nicht gross genug. Benutze vcolorTable.push_back!

Und gewöhn Dir mal eine bißchen saubere Schreibweise an, z.B:

Code: Alles auswählen

for(int y=0; y<image.height(); y++)
	{
		unsigned char *pDst=image.scanLine(y);

		for(int x=0; x<image.width(); x++)
		{
                         pDst[x]=0;
		}
	}
Und setPixel nimm bitte nicht, dass ist viel zu langsam!

Verfasst: 17. August 2009 13:22
von Curtis Newton
androphinx hat geschrieben:und warum nimmst du nicht die funktion pixel() ??? die ist einfacher und sicherer, was solche fehler anbelangt...

Mfg androphinx
Weil sie nichts mit dem Fehler zu tun hat.

C.

Verfasst: 17. August 2009 13:24
von Curtis Newton
franzf hat geschrieben:Du hast das warning zu scanline gelesen?
Warning: If you are accessing 32-bpp image data, cast the returned pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the pixel value. You cannot use the uchar* pointer directly, because the pixel format depends on the byte order on the underlying platform. Use qRed(), qGreen(), qBlue(), and qAlpha() to access the pixels.
Damit ist es klar dass diese Zeile

Code: Alles auswählen

*(m_Image.scanLine(j) + i)  = (uchar) 0;
nur Probleme bereiten kann.
Nein, er benutzt ja extra QImage::Format_Indexed8! Die Zeile bereitet überhaupt keine Probleme, ist nur schlecht zu lesen. Und bereitet damit den nächsten Programmierer, der den Code lesen muss, Probleme ;-)
franzf hat geschrieben: Warum verwendest du denn nicht einfach setPixel?
"Note that if you create an 8-bit image manually, you have to set a valid color table on the image as well." Er muss also eh eine palette setzen, egal was er nimmt!

C.