[vtkusers] Fast conversion from vtkImageData to QImage?
Prashanth Udupa
prashanth.udupa at gmail.com
Fri Jan 29 09:30:55 EST 2010
Thanks Michael, John and Jeff for the really useful tips :-)
Based on the inputs, first I wrote a simple Qt/C++ profiler class.
#include <QTime>
class FunctionProfiler
{
public:
FunctionProfiler(const QString& func) {
m_function = QMetaObject::normalizedSignature( qPrintable(func) );
m_function = m_function.remove("__thiscall");
m_function = m_function.remove("__stdcall");
m_function = m_function.remove("__cdecl");
m_startTime = QTime::currentTime();
}
~FunctionProfiler() {
qint32 msecs = m_startTime.msecsTo( QTime::currentTime() );
qDebug("PROFILE: (%5d) %s", msecs, qPrintable(m_function));
}
private:
QString m_function;
QTime m_startTime;
};
#define PROFILE_THIS_FUNCTION FunctionProfiler functionProfiler(Q_FUNC_INFO);
Now, I can just insert the PROFILE_THIS_FUNCTION macro on the first
line of any function to get atleast an approximate idea of the time
spent in the createQImage() function.
Initially the createQImage() function [based on code from my previous
email] was taking as much as 48 milliseconds for a 512 x 512 image.
Now it takes 4-6 milliseconds (as shown by the qDebug() output below)
PROFILE: ( 5) class QImage
RadGUI::VTKImageGraphicsViewData::createQImage(int,int,vtkUnsignedCharArray*)const
Jeff Baumes: Thanks for the tip. I did take a look at
vtkQImageToImageSource::RequestData() implementation. For me, the
pointer math was a little difficult to get. But I am sure
reverse-implementing the function could possibly make the conversion
from vtkImageData to QImage still faster. I will give it a try in the
coming days.
-----------------------------------
// This is the code that I am currently using
QImage createQImage(vtkImageData* imageData)
{
PROFILE_THIS_FUNCTION;
if(!imageData)
return QImage();
int width = imageData->GetDimensions()[0];
int height = imageData->GetDimensions()[1];
vtkUnsignedCharArray* scalars =
vtkUnsignedCharArray::SafeDownCast(imageData->GetPointData()->GetScalars());
if(!width || !height || !scalars)
return QImage();
switch(scalars->GetNumberOfComponents())
{
case 1:
return createQImage1(width, height, scalars);
case 2:
return createQImage2(width, height, scalars);
case 3:
return createQImage3(width, height, scalars);
case 4:
return createQImage4(width, height, scalars);
}
return QImage();
}
QImage createQImage1(int width, int height, vtkUnsignedCharArray* scalars)
{
QImage qImage(width, height, QImage::Format_ARGB32);
vtkIdType tupleIndex=0;
int qImageBitIndex=0;
QRgb* qImageBits = (QRgb*)qImage.bits();
unsigned char* scalarTuples = scalars->GetPointer(0);
for(int j=0; j<height; j++)
{
for(int i=0; i<width; i++)
{
unsigned char* tuple = scalarTuples+(tupleIndex++);
QRgb color = qRgba(tuple[0], tuple[0], tuple[0], 255);
*(qImageBits+(qImageBitIndex++))=color;
}
}
return qImage;
}
QImage createQImage2(int width, int height, vtkUnsignedCharArray* scalars)
{
QImage qImage(width, height, QImage::Format_ARGB32);
vtkIdType tupleIndex=0;
int qImageBitIndex=0;
QRgb* qImageBits = (QRgb*)qImage.bits();
unsigned char* scalarTuples = scalars->GetPointer(0);
for(int j=0; j<height; j++)
{
for(int i=0; i<width; i++)
{
unsigned char* tuple = scalarTuples+(tupleIndex++*2);
QRgb color = qRgba(tuple[0], tuple[0], tuple[0], tuple[1]);
*(qImageBits+(qImageBitIndex++))=color;
}
}
return qImage;
}
QImage createQImage3(int width, int height, vtkUnsignedCharArray* scalars)
{
QImage qImage(width, height, QImage::Format_ARGB32);
vtkIdType tupleIndex=0;
int qImageBitIndex=0;
QRgb* qImageBits = (QRgb*)qImage.bits();
unsigned char* scalarTuples = scalars->GetPointer(0);
for(int j=0; j<height; j++)
{
for(int i=0; i<width; i++)
{
unsigned char* tuple = scalarTuples+(tupleIndex++*3);
QRgb color = qRgba(tuple[0], tuple[1], tuple[2], 255);
*(qImageBits+(qImageBitIndex++))=color;
}
}
return qImage;
}
QImage createQImage4(int width, int height, vtkUnsignedCharArray* scalars)
{
QImage qImage(width, height, QImage::Format_ARGB32);
vtkIdType tupleIndex=0;
int qImageBitIndex=0;
QRgb* qImageBits = (QRgb*)qImage.bits();
unsigned char* scalarTuples = scalars->GetPointer(0);
for(int j=0; j<height; j++)
{
for(int i=0; i<width; i++)
{
unsigned char* tuple = scalarTuples+(tupleIndex++*4);
QRgb color = qRgba(tuple[0], tuple[1], tuple[2], tuple[3]);
*(qImageBits+(qImageBitIndex++))=color;
}
}
return qImage;
}
-----------------------------------
Thanks and Regards,
Prashanth
More information about the vtkusers
mailing list