2012-06-28 4 views
2

Я ищу для отображения карт высот из видеоигры Battlefield 2 как изображения в моем приложении.
Я новичок в C++ и Qt, и это может быть прямолинейно, но у меня возникают проблемы с отображением изображения в оттенках серого 16-bit 1025x1025 2101250. В файле нет заголовка. Мне нужен доступ к отображаемым пикселям (не обязательно должна быть точность пикселя), поэтому я могу указать на пиксель и получить его значение.С C++ и Qt как я могу отобразить 16-битный необработанный файл в качестве изображения?

То, что я пытался

Я загрузил бинарные данные в QByteArray из 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.

ответ

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

+0

Когда я впервые попробовал это, я расстроился, когда он не сработал. Сегодня я попробовал еще раз, прочитав еще кое-что на C++ и Qt, и я действительно получил его для работы. Теперь я показываю изображение точно так, как хочу (мне нужно сделать какое-то преобразование, но это для другого вопроса). Я хотел бы поблагодарить вас за то, что вы нашли время, чтобы ответить на мой вопрос, и помогли мне с моими попытками начинающих. Также я благодарю других ответов, это то, что я мог понять! – aPerfectMisterMan

0

1. В основном, что вам нужно сделать, это нарисовать пиксели внутри виджета.

Таким образом, во-первых, создать приложение, которое имеет диалог, затем сделать в диалоговом окне, используя рекомендации от:

Qt4 How to draw inside a widget?

И для документации QPainter: http://qt-project.org/doc/qt-4.8/QPainter.html

Обратите внимание, что вы будете необходимо создать QBrush при просмотре пикселей: http://doc.qt.nokia.com/4.7/qbrush.html

Это будет довольно медленно :(

2. Еще более продвинутым решением было бы создать QImageReader и связанный с ним изображения IO плагин читать ваш формат (http://qt-project.org/doc/qt-4.8/qimagereader.html), а затем создать QPixmap с читателем изображения (http://qt-project.org/doc/qt-4.8/qpixmap.html#fromImageReader) и создать QBrush с данным QPixmap и использования это нарисовать :)

+3

Я думаю, что его проблема связана с 16-разрядной загрузкой, не поддерживаемой QT. –

+0

Вы правы :) Я отредактировал ответ – fritzone

1

Вы не можете использовать loadFromData, потому что он не поддерживает сырье (см Reading and Writing Image Files).

Вы не можете найти 16-битное сырье в supported format, поэтому я считаю, что лучшим решением является конвертер между загрузкой изображения и отображением изображения.

Создайте новый 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 */ 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^