2

我希望在我的应用程序中将视频游戏《战地 2》中的高度图显示为图像。
我是 C++ 和 Qt 的新手,它可能很简单,但我遇到的问题是显示灰度16-bit 1025x1025 2101250字节图像。该文件没有标题。我需要访问显示的像素(不必是完美的像素精度),这样我就可以指向一个像素并获取它的值。

我试过的

我已经将二进制数据QByteArray从 QFile 加载到一个 QFile 中,并且我尝试使用该QImage::fromData函数制作图像,但我犯了很多错误并且花了很多时间没有走得很远。我希望在这里发帖能给我提供我需要进步的线索。这是我的代码:

void LearningBinaryReader::setupReader()
{
    qDebug("Attempting to open file..");
    QFile file("HeightmapPrimary.raw");
    if (!file.open(QFile::ReadOnly))
    {
        qDebug("Could not open file");
        return;
    } else {
        qDebug() << file.fileName() << " opened";
    }
    QByteArray data = file.readAll();
    file.flush();
    file.close();

    qDebug() << data.count() << "bytes loaded.";
}

从这里我不知道该怎么办。我已经阅读了一些 Qt 文档,但我是新手,我需要一个正确方向的指南来理解这个问题并获得解决方案。

请注意,我几乎是一个初学者,所以不要忽视我可能没有想到的简单解决方案。我想只使用 Qt 框架来做到这一点。

4

3 回答 3

2

只是一个猜测。也许尝试这样的事情?

#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')

编辑:哎呀,QImage::Format_RGB32而不是QImage::Format_RGB

于 2012-06-28T06:53:48.287 回答
1

您不能使用loadFromData,因为它不支持 raw (请参阅读取和写入图像文件)。

您找不到支持格式的 16 位原始数据,因此我认为最好的解决方案是在图像加载和图像显示之间使用转换器。

创建一个新的 QImage,使用 qt 支持的格式。

QImage* image = new QImage(1025, 1025, QImage::Format_RGB888);

然后加载源图像并将其转换为 RGB888。您的图像非常大,因此请避免使用readAll(). 您可以使用这个简单的转换器(见下文)或现有库中的转换器(如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 */
}
于 2012-06-28T07:06:15.457 回答
0

1.基本上你需要做的是在一个小部件内绘制你的像素。

因此,首先创建一个具有对话框的应用程序,然后使用以下建议在对话框上绘制:

Qt4 如何在小部件内绘制?

对于 QPainter 文档:http: //qt-project.org/doc/qt-4.8/QPainter.html

请注意,您需要在遍历像素时创建一个 QBrush:http: //doc.qt.nokia.com/4.7/qbrush.html

这会很慢:(

2. 另一个更高级的解决方案是创建一个 QImageReader 和一个关联的 Image IO 插件来读取您的格式(http://qt-project.org/doc/qt-4.8/qimagereader.html),然后使用图像创建一个 QPixMap阅读器(http://qt-project.org/doc/qt-4.8/qpixmap.html#fromImageReader)并使用给定的 QPixmap 创建一个 QBrush 并使用它来绘制 :)

于 2012-06-28T06:49:18.500 回答