Russian Qt Forum

Qt => Общие вопросы => Тема начата: -QT- от Октябрь 13, 2008, 19:03



Название: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 13, 2008, 19:03
Собственно сабж.

Пробовал по разному:

Открываю через QFile()

Код:
QDataStream in(&file)
in >> lbArray;
...
lbArray += file.readLine();
...
lbArray = file.readAll();
...

Загружает только символы до 0х01, а потом фига
Кто знает пните на путь истинный.


Название: Re: Как загрузить BMP-файл в QByteArray
Отправлено: -QT- от Октябрь 13, 2008, 19:17
Нашел еще вот это:
http://www.qtforum.org/post/91477/qimage-qbytearray-qstring.html?highlight=QByteArray+QFile#post91477
Проверю завтра утром, на работе но может что-то еще есть.

Код:
#include <QCoreApplication>
#include <QImage>
#include <QFile>
#include <QByteArray>
#include <QBuffer>


int main(int argc, char *argv[])
{
      QCoreApplication app(argc, argv);
     
      QImage image("test.png");
      QByteArray ba;
      QBuffer buf(&ba);
      image.save(&buf, "BMP");
     
      QByteArray compressed = qCompress(ba, 1); // better just open file with QFile, load data, compress and toHex?
      QByteArray hexed = compressed.toHex();
      // save to a file
      QString str(hexed);
      QFile f("test.hex");
      if (f.exists())
          f.remove();
      if (f.open(QFile::WriteOnly))
      {
          f.write(str.toLatin1()); // holds only 0..f nothing special.
      }
      else
          qDebug("failed to open file \"test.hex\"");
      f.close();
      ////----------
      if (f.open(QFile::ReadOnly))
      {
          QByteArray read = f.readAll();
          f.close();
          QString rStr = QString::fromLatin1(read.data(), read.size());
          if (rStr != str)
              qDebug("Writed and read two different hexed strings.");
          QByteArray readCompressed = QByteArray::fromHex(rStr.toAscii());
          if (readCompressed != compressed)
              qDebug("bytes before hexing and dehexing _is_ different.");
          QByteArray readDecompressed = qUncompress(readCompressed);
          if (readDecompressed != ba)
              qDebug("bytes before and after compressions are different.");
          QImage readImg;
          //QBuffer readBuf(&readDecompressed);
          readImg.loadFromData(readDecompressed);
          if (readImg.isNull())
              qDebug("The image is null. Something failed.");
          readImg.save("test.bmp");
      }
      else
          qDebug("failed to open test.hex file for reading");
      return 0;
}


Название: Re: Как загрузить BMP-файл в QByteArray
Отправлено: -QT- от Октябрь 13, 2008, 19:35
Кстати долго искал решение для конвертации QByteArray & QBitArray
по ходу нашел вот это:
Код:
#include <QFile>
#include <QByteArray>
#include <QBitArray>
#include <QVariant>
#include <IOStream>

int main(int argc, char* argv[])
{
        QFile file("C:/testfile.txt");
        if (!file.open(QIODevice::ReadOnly))
        {
                std::cout << "Could not open file" << std::endl;
                return 1;
        }

        QByteArray input = file.readAll();

        std::cout << input.size() << std::endl;

        QDataStream stream(input);

        QBitArray bita;
        bita.fill(0,700);

        for (int i = 0; i < 700; ++i)
        {
                std::cout << bita[i];
        }


        stream >> bita;

        for (int i = 0; i < 700; ++i)
        {
                std::cout << bita[i];
        }

        std::cout << std::endl << "Size: " << bita.size() << std::endl;

        file.close();

        return 0;
}


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 14, 2008, 10:17
Продолжаем поиск решения...
Нужно загрузить файл в бинароном виде.
После чего засунуть в ком порт.
Уважаемые гуру, ткните где копать !

Пробовалось так:
char *fileChar = myArray.data(); - нифига
...
и так:
file.read(fileChar, sizeof(&file)); - нифига
...
и так:
QDataStream in(&file);
in >> fileChar;

Результат одинаковый, или я туплю или чтото тут не то !


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 14, 2008, 13:41
Получается такая фигня:

Код:
while ( !file.atEnd() )
{
   myArray.append( file.readLine() );
}
char *fileChar = myArray.data();
int lnSize = sizeof( fileChar );
file.size() = 108269
myArray.size() = 108269
sizeof( fileChar ) = 4
Оказывается что при конвертации из QByteArray в char* передаются не все символы.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: Rcus от Октябрь 14, 2008, 13:58
странно это, у меня работает и так:
Код:
int main(int argc, char** argv)
{
QFile f(argv[1]);
if (!f.open(QIODevice::ReadOnly)) qFatal("file open error");
QByteArray b = f.readAll();
if (b.isEmpty()) qFatal("%s",qPrintable(f.errorString()));
return 0;
}
Код:
main@RCEEE:/media/disk/proof_of_concept$ ./main a.bmp
file size:2677286
array size:2677286
насчет QByteArray::data(). Этот метод не занимает конвертированием, а возвращает указатель на внутренний массив.
P.S. sizeof(char*)==sizeof(void*)==4 для архитектуры i386


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 14, 2008, 14:46
QByteArray myArray = ( file.readAll() );
qDebug() << myArray ;
============================
myArray.size = 108269
qDebug() = "BMv "
============================
тоесть в дебаге я вижу только 4 байта, а в массиве 108269 их.
И так в любом положении...
почему только 4 байта где остальные.
Если читаю через QTextStream в QString то символов больше но
тоже не в размер файла, да и файл мне нужно засандалить в ком-порт потом.



Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: pastor от Октябрь 14, 2008, 14:53
QByteArray myArray = ( file.readAll() );
qDebug() << myArray ;
============================
myArray.size = 108269
qDebug() = "BMv "
============================
тоесть в дебаге я вижу только 4 байта, а в массиве 108269 их.
И так в любом положении...
почему только 4 байта где остальные.
Если читаю через QTextStream в QString то символов больше но
тоже не в размер файла, да и файл мне нужно засандалить в ком-порт потом.



Во-первых, пользоваться qDebug для вывода бинарного файла не есть гуд. Могут попасться непечатаемые символы которые qDebug невосприймет, возможно 5 байт и есть такой символ. Во-вторых qDebug может вывести только 8192 байт:

Цитировать
Warning: The internal buffer is limited to 8192 bytes, including the '\0'-terminator.

Самый лучший способ переспроверить правильность чтения это считать файл-источник и сохранить считаные данные в другой файл.

А какой реальный размер файла? 108269?


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 14, 2008, 14:55
размер 108269 байт.

то что есть непечатаемые символы это факт.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: pastor от Октябрь 14, 2008, 14:59
размер 108269 байт.

Ну тогда я невижу никакой проблемы. То что невыводит qDebug сожержимое буфера это не есть показатель неработоспособности. Еще раз повторюсь: сохрани сожержимое буфера в другой файл и сравни его с исходным.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 14, 2008, 15:19
Дааа... дело видно не в бобине ;)
файл записывается правильно размер в размер и внутри все чики.
а вот железяка на порту его принимать не желает.

Крот копает дальше... :)
Следующая серия с перекодированием в IBM866 - так как эта штуковина
других кодировок не понимает  :-\


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: pastor от Октябрь 14, 2008, 15:45
Крот копает дальше... :)
Следующая серия с перекодированием в IBM866 - так как эта штуковина
других кодировок не понимает  :-\

А здесь немножко подробнее... что именно неработает?

Немогу понять причет тут кодировки, если данные передаються как бинарные....


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 14, 2008, 15:59
Железяка воспринимает данные на входе как ср866,
по крайней мере вся предидущая работа с ней проходила через перекодирование
из Utf-8 в IBM866.
И сейчас я ей пихаю файл, а эта гадость его обрабатывать не желает, пишет что пакет
не правильный - такое было в самом начале когда я пытался ей передать на порт данные
в юникоде.
А вот как теперь правильно перекодировать это я пока не знаю.
Если знаешь помоги победить железяку.

Полетел домой... буду на форуме через 2 часа, наверное.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: Alex Custov от Октябрь 14, 2008, 16:38
http://www.opennet.ru/base/dev/iconv_c.txt.html


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: Tonal от Октябрь 14, 2008, 17:04
Кодировка для BMP - это сильно! :)
Брось заниматься глупостями. Лучше изучи доки по своей железячке - скорее всего она либо предпологает какой-то специальный заголовок для картинки, либо ожидает не "сырые" данные а например в base64, а может и то и другое.
Кроме того, она может не понимать какие-то из разновидностей BMP формата.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 14, 2008, 20:00
Цитировать
Кодировка для BMP - это сильно!
Брось заниматься глупостями. Лучше изучи доки по своей железячке - скорее всего она либо предпологает какой-то специальный заголовок для картинки, либо ожидает не "сырые" данные а например в base64, а может и то и другое.
Кроме того, она может не понимать какие-то из разновидностей BMP формата.

просветите по поводу форматов.
Кодировка в ВМР это конечно нонсенс но я передаю данные в ком-порт с помощью QextSerialPotr и использую для этого
QByteArray  который, как мне известно может хранить данные в UTF-8. Но факт на лицо железяка пакет не принимает и плюется ошибками. Все остальные пакеты, которые я формирую проходят перекодирование, но они формируются из
QString & char* в QByteArray.

По поводу доки все проштудировано и проконсультировано с производителем железа. Если они ничего не утаили :)
то получает она(железка) данные в формате 0х1В+ВМР после того как я отправлю контрольный пакет и получу в ответ байт
готовности к приему данных.
Все так и идет, только при передаче данных возникает таймаут, что означает что за отведенное время получено больше или
меньше информации чем требуется.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 14, 2008, 20:03
http://www.opennet.ru/base/dev/iconv_c.txt.html
Статья хорошая, но к кроссплатформенности не имеет никакого отношения.
Привязка к платформе не возможна по первичным требованиям.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: Alex Custov от Октябрь 14, 2008, 20:34
iconv есть в POSIX.1-2001, хотя я тут тоже не понимаю причём тут кодировки к бинарным данным. Тестируйте железку, что она от вас ожидает, а что вы шлёте.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: Tonal от Октябрь 14, 2008, 22:48
UTF-8 - это кодировка текста. А у тебя бинарные данные. Так что не мешай тёплое с мягким.
QByteArray хранит массив байтов. Ему всё равно что именно ты туда положил текст в какой-нибудь кодировке или BMP-шку.

В чём могут быть проблемы при передаче:
1. Железка может ожидать конкретный подформат (например только чёрнобелые снизу вверх)
2. Железка может ожидать не весь файл, а только структуру с изображением (см. как устроен файл BMP)
3. Ты можешь посылать неверно, например, ожидается байт со значением 0х1В и сразу за ним данные ВМР а у тебя там может проскочить ещё 1, 2 левых байта.
4. Есть ограничение на размер ВМР-шки которую можно залить.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: lit-uriy от Октябрь 15, 2008, 03:02
железка получающая картинку, потом ее будет показывать? Если так, то возможно ее разрешение не корректно для данной железки.


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 15, 2008, 09:02
В чём могут быть проблемы при передаче:
1. Железка может ожидать конкретный подформат (например только чёрнобелые снизу вверх)
А как проверить что файл действительно чёрнобелый, это каким-то образом
отображается в заголовке или есть другие признаки ?


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: Tonal от Октябрь 15, 2008, 10:58
В файле содержится вся информация нужная для отображения. :)
Хотя получить её можно и из QPixmap или QImage - свойство depth.
Ну и вообще ассистент по ним почитай. :)


Название: Re: Как загрузить BMP-файл в QByteArray (в бинарном виде)
Отправлено: -QT- от Октябрь 17, 2008, 10:38
Всем спасибо за ответы !

Дело было в двух вещах.
Первый баг затихарили производители железа, что передавать блок данных
нужно сразу в течении 200 мс.
А второй подкрался в том что нужно передавать черно-белое изображение в реально
однобитовом цвете, :) а не черно-белое в многобитной кодировке, это мне нужно было
внимательнее выискивать информацию в доке и спецификации.

А по итогу все заработало как часы.