I am looking to display heightmaps from the video game Battlefield 2 as images in my application.
I am new to C++ and Qt and it might be straight forward but what I am h
1. Basically what you need to do is to draw your pixels inside a widget.
So, firstly create an application which has a dialog, then draw on the dialog using the recommendations from:
Qt4 How to draw inside a widget?
And for the QPainter documentation: http://qt-project.org/doc/qt-4.8/QPainter.html
Notice, that you will need to create a QBrush while going through the pixels: http://doc.qt.nokia.com/4.7/qbrush.html
This will be pretty slow :(
2. Another more advanced solution would be to create a QImageReader and an associated Image IO plugin to read your format ( http://qt-project.org/doc/qt-4.8/qimagereader.html ) then create a QPixMap with the image reader ( http://qt-project.org/doc/qt-4.8/qpixmap.html#fromImageReader ) and create a QBrush with the given QPixmap and use it to draw :)
Just a guess. Maybe try something like this?
#include <QColor>
...
QByteArray data=file.readAll();
// create an empty image of the right size. We'll use 32-bit RGB for simplicity
QImage img(1025,1025, QImage::Format_RGB32);
// Access the image at low level. From the manual, a 32-bit RGB image is just a
// vector of QRgb (which is really just some integer typedef)
QRgb *pixels=reinterpret_cast<QRgb*>(img.bits());
// Now copy our image data in. We'll assume 16-bit LE format for the input data.
// Since we only have 8 bits of grayscale color resolution in a 32-bit RGB, we'll
// just chop off the most significant 8 bits (the second byte of each pair) and
// make a pixel out of that. If this doesn't work, our assumption might be off --
// perhaps assume 16-bit BE format. In that case we'd want the first byte of each
// pair.
for (size_t i=0;2*i<data.size();++i)
{
uchar pixel_msb=data[2*i+1]; // or maybe try =data[2*i+0]
pixels[i]=qRgb(pixel_msb, pixel_msb, pixel_msb);
}
// (do something with the resulting 'img')
edit: oops, QImage::Format_RGB32
instead of QImage::Format_RGB
You cannot use loadFromData
, because it does not support raw (see Reading and Writing Image Files).
You can't find 16bit raw in supported format so I think the best solution is using a converter between the image loading and the image displaying.
Create a new QImage, with a format supported by qt.
QImage* image = new QImage(1025, 1025, QImage::Format_RGB888);
Then load the source image and convert it to RGB888. Your image is very big, so avoid loading it all with readAll()
. You can use this simple converter (see below) or a converter from an existing library (like Magick++).
QFile file("HeightmapPrimary.raw");
if (!file.open(QFile::ReadOnly))
{
qDebug("Could not open file");
return;
}
uint16_t buf;
uchar* dst = image->bits();
while (readData(&buf, 2)) {
dst[0] = buf / 256; /* from 16bit to 8bit */
dst[1] = buf / 256;
dst[2] = buf / 256;
dst += 3; /* next pixel */
}