QImage in Grösse limitiert?

Alles rund um die Programmierung mit Qt
oggo
Beiträge: 9
Registriert: 16. Februar 2008 18:02

QImage in Grösse limitiert?

Beitrag von oggo »

Ich möchte ein grösseres Bild machen. Wenn ich nun folgendes

QImage img( width, height, format);
bool b = img.isNull();

schreibe, gibt mit die zweite Funktion ab einer gewissen Grösse
false zurück. Das Grösste, was noch ging war ~20000x 15000.
Ich habs auch in einem kleinen Programm probiert, dass nur aus dem
obigen code besteht, um allfällige ander Probleme zu eliminieren.

Ist das ein Bug? Oder hab ich was falsch verstanden?
Lässt sich das beheben?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Das entspricht ca. 1GByte. Wieviel Speicher hast du frei?
oggo
Beiträge: 9
Registriert: 16. Februar 2008 18:02

Beitrag von oggo »

2Gb ram, 60 Gb auf der Hd
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

??? Ich glaube, dir war der Sinn meiner Frage nicht klar...
oggo
Beiträge: 9
Registriert: 16. Februar 2008 18:02

Beitrag von oggo »

Kann gut sein, was willst Du denn wissen?
Wieviel ram zur laufzeit vor der erstellung des bildes frei ist?
Das sind dann ungefähr 1.5 Gb.
Oder stell deine Frage nochmal ein wenig genauer.
Danke schonma für die schnellen Antworten.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Kurz gesagt, Qt kann nicht genügend Speicher anfordern, um ein Bild dieser Größe im Speicher abzulegen.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

20.000 * 15.000 * 4Bytes = 1.200.000.000Bytes
1.200.000.000Bytes / 1024 /1024 ~= 1200MB
Und jetzt sag mir ein System dass immer 1.2GB freien zusammenhängenden Speicher hat...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
oggo
Beiträge: 9
Registriert: 16. Februar 2008 18:02

Beitrag von oggo »

Ok, ihr habt ja recht. Obwohl das mit 20000x15000 ja noch funktionierte.
Auf jeden fall ist mein Ziel eigentlich nur eine Bitmap (black&white) rauszuschreiben. Nach einigem rumfumeln auch mit QImage::Format_Mono krieg ich das Gefühl, dass die QImage::save(...) methode 1bit-bilder nicht richtig handeln kann. Nach Bmp sollte ja eigentlich funktionieren.
Hat da jemand Erfahrung? Ich find leider nirgends ein codebeispiel für 1bit bilder mit Qt.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Gute Fehlerbeschreibung... wir brauchen Code!
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
oggo
Beiträge: 9
Registriert: 16. Februar 2008 18:02

Beitrag von oggo »

Also, hier mal der Code, ist ein Auschnitt aus QGLViewer, savesnapshot.cpp.
Ich hab versucht, ein paar Zeilen so abzuändern, dass das finale Bild, image genannt, ein 1bit bild ist. Das ganze wird dann beim kopieren aus den subimages nach s/w gewandelt.
Das Resultat ist aber, dass das gespeicherte Bild nur schwarz ist.
Die subimages, die ich mir zu kontrolle rauschreibe, sind aber korrekt.

Code: Alles auswählen

  
#if QT_VERSION >= 0x040000
    //QImage image(finalSize.width(), finalSize.height(), QImage::Format_ARGB32);
	 QImage image(finalSize.width(), finalSize.height(), QImage::Format_Mono);
	 image.setColor( 0, QRgb( Qt::black ));
	 image.setColor( 1, QRgb( Qt::white ));

#else
  QImage image(finalSize.width(), finalSize.height(), 32);
#endif

  if (image.isNull())
    {
      QMessageBox::warning(this, "Image saving error",
			   "Unable to create resulting image",
			   QMessageBox::Ok, QMessageBox::NoButton);
      return false;
    }

  // ProgressDialog::showProgressDialog(this);

  double deltaX = 2.0 * xMin * subSize.width() / finalSize.width();
  double deltaY = 2.0 * yMin * subSize.height() / finalSize.height();

  int nbX = finalSize.width() / subSize.width();
  int nbY = finalSize.height() / subSize.height();

  // Extra subimage on the border if needed
  if (nbX * subSize.width() < finalSize.width())
    nbX++;
  if (nbY * subSize.height() < finalSize.height())
    nbY++;

  makeCurrent();

  int count=0;
  for (int i=0; i<nbX; i++)
    for (int j=0; j<nbY; j++)
      {
	preDraw();
	// Change projection matrix
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if (camera()->type() == qglviewer::Camera::PERSPECTIVE)
	  glFrustum(-xMin + i*deltaX, -xMin + (i+1)*deltaX, yMin - (j+1)*deltaY, yMin - j*deltaY, zNear, zFar);
	else
	  glOrtho(-xMin + i*deltaX, -xMin + (i+1)*deltaX, yMin - (j+1)*deltaY, yMin - j*deltaY, zNear, zFar);
	glMatrixMode(GL_MODELVIEW);
	  
	draw();
	postDraw();

	// ProgressDialog::hideProgressDialog();
	// qApp->processEvents();

	QImage snapshot = grabFrameBuffer(true);

	// ProgressDialog::showProgressDialog(this);
	// ProgressDialog::updateProgress(count / (float)(nbX*nbY),
	// "Generating image ["+QString::number(count)+"/"+QString::number(nbX*nbY)+"]");
	// qApp->processEvents();

#if QT_VERSION >= 0x040000
	QImage subImage = snapshot.scaled(subSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
	subImage.save(fileName + QString::number(count), snapshotFormat().toLatin1().constData(), snapshotQuality());
#else
# if QT_VERSION >= 0x030000
	QImage subImage = snapshot.scale(subSize, QImage::ScaleFree);
# else
	QImage subImage = snapshot.smoothScale(subSize.width(), subSize.height());
# endif
#endif

	// Copy subImage in image
	for (int ii=0; ii<subSize.width(); ii++)
	{
	    int fi = i*subSize.width() + ii;
	    if (fi == image.width())
	      break;
	    for (int jj=0; jj<subSize.height(); jj++)
	    {
			int fj = j*subSize.height() + jj;
			if (fj == image.height())
				break;

			//changed:
			//image.setPixel(fi, fj, subImage.pixel(ii,jj));
			if( qGray( subImage.pixel(ii,jj) ) > 125 )
			{
				image.setPixel( fi, fj, 1 );
			}else{
				image.setPixel( fi, fj, 0);
			}
			//changed
		}
	  }
	  
	count++;
      }
  
#if QT_VERSION >= 0x040000
  bool saveOK = image.save(fileName, snapshotFormat().toLatin1().constData(), snapshotQuality());
#else
  bool saveOK = image.save(fileName, snapshotFormat(), snapshotQuality());
#endif

[/quote]
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ohne es genauer anzusehen.
image ist immer noch in 32Bit aRGB-Mode - da wirst Du mit setPixel(0/1) nicht viel ausrichten können.
Ausserdem gibt es QImage::convertToFormat()
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
oggo
Beiträge: 9
Registriert: 16. Februar 2008 18:02

Beitrag von oggo »

Ich möchte ja mit:

QImage image(finalSize.width(), finalSize.height(), QImage::Format_Mono);

(3.Zeile im obigen Code ) 1bit representation ausrichten, nich mit setPixel.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Außerdem gibt es Qt::color0 und Qt::color1 als 'Farben' für Bitmaps.
oggo
Beiträge: 9
Registriert: 16. Februar 2008 18:02

Beitrag von oggo »

Ok, aber die verwendung von Qt::color0 / Qt::color1 löst ja das Problem nicht, oder?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Durch das ganze Qt3/Qt4 Zeugs habe ich es nicht gesehen das Du mono benutzt - warum überhaupt Qt3??
setColor() ist überflüssig und ggf. kontraproduktiv - da wie uplsala schon sagte '0' und '1' nicht wirklich weiss und schwarz sind.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten