Loading an image from raw data with Qt - c++

I am quite suprised since I'm not able to find any method that loads an image from raw data. Is there any elegant way to do it? I just need to create a QImage or similar from raw bitmap binary data (no header).

You can create a QImage object from raw data with the ctor that takes an array of uchars.
You need to specify the format of the data given to the QImage (RGB, RGBA, Indexed, etc.)
QImage ( uchar * data, int width, int height, Format format )
QImage ( const uchar * data, int width, int height, Format format )
QImage ( uchar * data, int width, int height, int bytesPerLine, Format format )
QImage ( const uchar * data, int width, int height, int bytesPerLine,
Format format )
http://doc.qt.digia.com/qt/qimage.html
E.g.:
uchar* data = getDataFromSomewhere();
QImage img(data, width, height, QImage::Format_ARGB32);
Hope that helps.

your question is not clear. use Qpixmap. and Qbyte array. its very easy.
QPixmap pic;
pic.loadFromData(array); //array contains a bite array of the image.
label->setPixmap(pic); //do what ever you want from the image. here I set it to a lable.

Related

OpenCV how to encode raw image information for imencode?

I am in C++.
Assume some mysterious function getData() returns all but only the pixel information of an image.
i.e a char* that points to only the pixel information with no metadata (no width, length, height, nor channels of any form)
Thus we have:
unsigned char *raw_data = getData();
Then we have another function that returns a structure containing the metadata.
eg:
struct Metadata {
int width;
int height;
int channels;
//other useful fields
}
I now need to prepend the object metadata in the correct way to create a valid image buffer.
So instead of [pixel1, pixel2, pixel3 ...]
I would have, for example [width, height, channels, pixel1, pixel2, pixel3...]
What is the correct order to prepend the metadata and are width, height and channels enough?
You can use Mat constructor to create an image from data and meta data
Mat::Mat(int rows, int cols, int type, void* data, size_t
step=AUTO_STEP); // documentation here
cv::Mat image = cv::Mat(height, width, CV_8UC3, raw_data);
type argument specifies the number of channels and data format. For example, typical RGB image data is unsigned char and the number of channels is 3 so its type = CV_8UC3
Available OpenCV Mat types are defined cvdef.h

DevIL/OpenIL isn't loading alpha channel

I am having an issue where the .png image that I want to load as a byte array using DevIL is not having an alpha channel.
A complete black image is also appearing as having alpha channel values as 0.
This is my image loading function:
DevILCall(ilGenImages(1, &m_ImageID));
DevILCall(ilBindImage(m_ImageID));
ASSERT("Loading image: " + path);
DevILCall(ilLoadImage(path.c_str()));
GraphicComponents::Image image(
ilGetData(),
ilGetInteger(IL_IMAGE_HEIGHT),
ilGetInteger(IL_IMAGE_WIDTH),
ilGetInteger(IL_IMAGE_BITS_PER_PIXEL)
);
return image;
The Image object I am using is as follows:
struct Image
{
ILubyte * m_Image;
const unsigned int m_Height;
const unsigned int m_Width;
const unsigned int m_BPP;
Image(ILubyte imageData[ ], unsigned int height, unsigned int width, unsigned int bpp);
~Image();
};
And this is how I am printing out the image data for now:
for(unsigned int i = 0; i < image->m_Height*image->m_Width*4; i+=4)
{
LOG("Red:");
LOG((int) image->m_Image[i]);
LOG("Green:");
LOG((int) image->m_Image[i+1]);
LOG("Blue:");
LOG((int) image->m_Image[i+2]);
LOG("Alpha:");
LOG((int) image->m_Image[i+3]);
}
I also tried using the ilTexImage() to format the loaded image to RGBA format but that also doesn't seem to work. The printing loop starts reading garbage values when I change the maximum value of the loop variable to 4 times the number of pixels in the image.
The image is also confirmed to have an alpha channel.
What might be going wrong here?
EDIT: ilGetInteger(IL_IMAGE_BPP) is returning 3, which should mean RGB for now. When I use the ilTexImage() to force 4 channels, then ilGetInteger(IL_IMAGE_BPP) returns 4 but I still see garbage values popping up at the std output
The problem was fixed by a simple ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE) call after loading the image.
I suppose DevIL loads the image in RGB mode with unsigned byte values by default and to use otherwise, you need to convert the loaded image using ilConvertImage().

QImage: convert from grayscale to RGB with a color table

With Qt, I am trying to convert a Format_Indexed8 image to Format_RGB30 by using a custom conversion rule defined by a color table. I thought this would be simple, since QImage::convertToFormat can take a color table as an argument, but I can't make it work.
Here is my code:
QImage image = QImage(data, width, height, QImage::Format_Indexed8);
QVector<QRgb> colorTable(256);
for (int i = 0; i < 255; i++)
colorTable[i] = qRgb(255 - i, i, i);
image = image.convertToFormat(QImage::Format_RGB30, colorTable);
This code just gives me an image that is in RGB format, but that looks identical to the eye to the grayscale image.
I think the color table argument in QImage::convertToFormat is required to convert from RGB to indexed, while you're converting the other way around.
I would try setting the color table directly in the indexed file (source), using QImage::setColorTable, then call convertToFormat passing the format argument only:
QImage image = QImage(data, width, height, QImage::Format_Indexed8);
image.setColorTable(colorTable);
image = image.convertToFormat(QImage::Format_RGB30);
This is not necessary since Qt 5.5 (released in July of 2015). You can now use QImage::Format_Grayscale8. Your code would be simply:
QImage image{data, width, height, QImage::Format_Grayscale8};

Error in RGB to YUV conversion in FFmpeg

I am trying convert a RGB image into YUV.
I am loading image using openCV.
I am calling the function as follows:
//I know IplImage is outdated
IplImage* im = cvLoadImage("1.jpg", 1);
//....
bgr2yuv(im->imageData, dst, im->width, im->height);
the function to convert Color image to yuv image is given below.
I am using ffmpeg to do that.
void bgr2yuv(unsigned char *src, unsigned char *dest, int w, int h)
{
AVFrame *yuvIm = avcodec_alloc_frame();
AVFrame *rgbIm = avcodec_alloc_frame();
avpicture_fill(rgbIm, src, PIX_FMT_BGR24, w, h);
avpicture_fill(yuvIm, dest, PIX_FMT_YUV420P, w, h);
av_register_all();
struct SwsContext * imgCtx = sws_getCachedContext(imgCtx,
w, h,(::PixelFormat)PIX_FMT_BGR24,
w, h,(::PixelFormat)PIX_FMT_YUV420P,
SWS_BICUBIC, NULL, NULL, NULL);
sws_scale(imgCtx, rgbIm->data, rgbIm->linesize,0, h, yuvIm->data, yuvIm->linesize);
av_free(yuvIm);
av_free(rgbIm);
}
I am getting wrong output after conversion.
I am thinking this is due to padding happening in the IplImage.
(My input image width is not multiple of 4).
I updated linesize variable even after that I am not getting correct output.
Its working fine when I am using images whose width is multiple of 4.
Can anybody tell what is the problem in the code.
Check IplImage::align or IplImage::widthStep and use these to set AVFrame::linesize. For the RGB frame, for example, you would set:
frame->linesize[0] = img->widthStep;
The layout of the dst array can be whatever you want, it depends on how you're using it afterwards.
We need to do as follows:
rgbIm->linesize[0] = im->widthStep;
But I think output data from sws_scale() is not padded to make it multiple of 4.
So when you are copying this data (dest) again to IplImage this will
create problem in displaying, saving etc..
So we need to set widthStep=width as follows:
IplImage* yuvImage = cvCreateImageHeader(cvGetSize(im), 8, 1);
yuvImage->widthStep = yuvImage->width;
yuvImage->imageData = dest;

QPixmap::fromImage() gives segmentation fault in QX11PixmapData

I have written some code that looks more or less like this:
QVector<QRgb> colorTable(256);
QImage *qi = new QImage(lutData, imwidth,imheight, QImage::Format_Indexed8);
while (index < 256)
{
colorTable.replace(index, qRgb(2552,255, 255));
index++;
}
qi->setColorTable(colorTable);
QPixmap p(QPixmap::fromImage(*qi,Qt::AutoColor));
so lutData (unsigned char) is my indexes into the colorTable. This crashes on the last line of the snippet, and the actual line is in a library I cant see source to called QX11PixmapData. What am I doing wrong to cause this crash, or is it a Qt Bug?
I am running CentOS 5.5 if that matters.
Thanks!
The QImage constructor you called is:
QImage::QImage ( const uchar * data, int width, int height, Format format )
Which requires the scanline data to be 32-bit aligned. So make sure it is and also has enough bytes in it. Or you can use:
QImage::QImage ( uchar * data, int width, int height, int bytesPerLine, Format format )
Which allows specification of bytes per scanline without being 32-bit aligned. So you can call it this way:
QImage *qi = new QImage(lutData, imwidth, imheight, imwidth, QImage::Format_Indexed8);
Since for a index color image, the scanline bytes is the same as the width.