[vtkusers] How can I save the contents of a QVTKWidget as an image?

Mike Taverne mtaverne at engits.com
Tue Sep 15 09:47:28 EDT 2009


I decided to change the GUI so that the widget is always completely
visible (the save image function changes tabs just to show it) and used
this:
============
vtkPNGWriter* writer = vtkPNGWriter::New();
writer->SetInput(this->cachedImage());
writer->SetFileName(qPrintable(filename));
writer->Write();
writer->Delete();
============

However, there was one more very important thing I had to do:
Use "QVTKWidget::setAutomaticImageCacheEnabled(bool flag)" to set
"automaticImageCacheEnabled" to true!
================
// Description:
// Enables/disables automatic image caching. If disabled (the default),
// QVTKWidget will not call saveImageToCache() on its own.
virtual void setAutomaticImageCacheEnabled(bool flag);
virtual bool isAutomaticImageCacheEnabled() const;
================

I also implemented printing of the contents of a QVTKWidget in a not so
nice way, but which works (provided the widget is visible):
===============
void QVTKStructuredGridWidget::print()
{
QPrinter printer(QPrinter::HighResolution);

QPrintDialog *dialog = new QPrintDialog(&printer, this);
dialog->setWindowTitle(tr("Print Document"));
if (dialog->exec() != QDialog::Accepted)
return;

vtkRenderWindowInteractor* iren = NULL;
if (this->mRenWin) {
iren = this->mRenWin->GetInteractor();
}

if (!iren || !iren->GetEnabled()) {
return;
}

// if we have a saved image, use it
if (this->cachedImageCleanFlag) {
vtkUnsignedCharArray* array = vtkUnsignedCharArray::SafeDownCast(
this->mCachedImage->GetPointData()->GetScalars());
// put cached image into back buffer if we can
this->mRenWin->SetPixelData(0, 0, this->width() - 1, this->height() - 1,
array, !this->mRenWin->GetDoubleBuffer());
// swap buffers, if double buffering
this->mRenWin->Frame();
// or should we just put it on the front buffer?
return;
}

iren->Render();

int w = this->width();
int h = this->height();
QImage img(w, h, QImage::Format_RGB32);
vtkUnsignedCharArray* pixels = vtkUnsignedCharArray::New();
pixels->SetArray(img.bits(), w*h*4, 1);
this->mRenWin->GetRGBACharPixelData(0, 0, w - 1, h - 1, 0, pixels);

pixels->Delete();
img = img.rgbSwapped();
img = img.mirrored();

QPainter painter;//(this);
painter.begin(&printer);

// Adapt size of image to size of paper
int h_img = img.height();
int w_img = img.width();
int H = painter.viewport().height();
int W = painter.viewport().width();

QRect dest = painter.viewport();

double alpha = h_img / (double) w_img;
if (alpha*W <= H) {
dest.setWidth(W);
dest.setHeight((int)(alpha*W));
}
else {
dest.setWidth((int)(H / alpha));
dest.setHeight(H);
}

painter.drawImage(dest, img);
painter.end();
}
===============




More information about the vtkusers mailing list