PDA

View Full Version : Trying to make a Qimage from a char *



feraudyh
9th December 2013, 13:19
Hello,
I have Qt 5.1 and I am trying to display pictures I get from a scanner into a window.
My 8 bit grey scale image comes as an array called m_raw_data of type unsigned char *, and I know that its dimensions are 320x480.

I want to create a QImage structure to wrap it up so I can paint my widget.
I have the problem that the following code does not compile


QVector<QRgb> colorTable;
for(int i = 0; i < 256; i++){
colorTable.append(qRgb(i,i,i));
}
memset(m_raw_data, 0, DEFAULT_IMAGE_WIDTH*DEFAULT_IMAGE_HEIGHT);
m_image = new QImage(m_raw_data, DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT,QImage::F ormat_Indexed8);
m_image->setColorTable(colorTable);

The compiler says that the constructor QImage is ambiguous, and I am willing to supply the extra arguments, but I dont really dont know what they mean, as the documentation just says
typedef QImageCleanupFunction
A function with the following signature that can be used to implement basic image memory management:

void myImageCleanupHandler(void *info);
This typedef was introduced in QtGui 5.0.

This description is so short as to leave me speechless. There is no example either.
Thankyou for your attention
Henri

anda_skoa
9th December 2013, 14:35
I don't think passing a cleanup function will help to disambiguate, all those "raw data" constructors have it as the second to last argument.

You could try casting your array to one of the the two types used for the constructors' first argument.

Btw, your code doesn't make sense, you set your image data to 0 before creating the image.

Oh, and you most likely don't need to create QImage on the heap.

Cheers,
_

feraudyh
9th December 2013, 19:25
Thankyou for your reply.
I used memset because I was planning on changing the contents of the raw data and hoping that I could do this after the call to the QImage constructor.
Apparently this is not possible.

Still answer to what the cleanup function is supposed to do. It did disambiguate my function call by the way. I just passed one that did nothing.

ChrisW67
10th December 2013, 00:05
Your code compiles just fine here (it may not do what you expect but that's another problem). What is your actual error message and/or your actual code?


#include <QApplication>
#include <QImage>

int main(int argc, char **argv)
{
QApplication app(argc, argv);
const int DEFAULT_IMAGE_WIDTH = 320;
const int DEFAULT_IMAGE_HEIGHT = 480;
unsigned char m_raw_data[DEFAULT_IMAGE_WIDTH * DEFAULT_IMAGE_HEIGHT];
QImage *m_image;

// YOUR CODE
QVector<QRgb> colorTable;
for(int i = 0; i < 256; i++){
colorTable.append(qRgb(i,i,i));
}
memset(m_raw_data, 0, DEFAULT_IMAGE_WIDTH*DEFAULT_IMAGE_HEIGHT);
m_image = new QImage(m_raw_data, DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT,QImage::F ormat_Indexed8);
m_image->setColorTable(colorTable);
// END YOUR CODE

delete m_image;
return 0;
}



$ ~/Qt5.1.1/5.1.1/gcc_64/bin/qmake
$ make
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/home/chrisw/Qt5.1.1/5.1.1/gcc_64/mkspecs/linux-g++ -I. -I. -I/home/chrisw/Qt5.1.1/5.1.1/gcc_64/include -I/home/chrisw/Qt5.1.1/5.1.1/gcc_64/include/QtWidgets -I/home/chrisw/Qt5.1.1/5.1.1/gcc_64/include/QtGui -I/home/chrisw/Qt5.1.1/5.1.1/gcc_64/include/QtCore -I. -o main.o main.cpp
g++ -Wl,-O1 -Wl,-rpath,/home/chrisw/Qt5.1.1/5.1.1/gcc_64 -Wl,-rpath,/home/chrisw/Qt5.1.1/5.1.1/gcc_64/lib -o tt main.o -L/home/chrisw/Qt5.1.1/5.1.1/gcc_64/lib -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
$

anda_skoa
10th December 2013, 09:34
I used memset because I was planning on changing the contents of the raw data and hoping that I could do this after the call to the QImage constructor.
Apparently this is not possible.

Ah, no, that is indeed possible. Passing memory to the QImage constructor makes it use that memory, not a copy.

Alternatively you could let QImage create the memory and then access it via QImage::bits() or QImage::scanline().

Cheers,
_

xxxollixxx
10th December 2013, 10:41
I'm not sure about your problem, but I also wrote a RAW-Imageviewer. I pass the Data from a QFile to a Qbytearray to a QImage and then display it as a Pixmap on a Label. It works, but there was a problem, the image was not displayed correctly because I used the Format_Indexed8. Guess you also have to use rgb32 even if your images are 8bit grayscale. If you do so, you also will not need your colortable anymore. Here is a example:


void MainWindow::on_pushButton_clicked()
{
QFile file(filename[0]);
if (file.open(QIODevice::ReadOnly))
{
QByteArray ba=file.readAll();
QImage image(512,256,QImage::Format_RGB32);
int j=0, color;
for (int y=0; y<image.height(); y++)
{
for (int x=0; x<image.width(); x++)
{
color = ba.at(j);
image.setPixel(x,y,color+(color<<8)+(color<<16)); // here is the hex shift for rgb32 0xffRRGGBB
j++;
}
}
QPixmap pix2(QPixmap::fromImage(image));
ui->lb1->setPixmap(pix2);
file.close();
}
else{...}
}

Hope this is helpful :D

Best regards,

Olli