Как читать 8-битные RAW-данные из файла - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть 8-битные необработанные данные, представляющие изображение в градациях серого (значение int 0-255) в файле, похожем на это:

0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 001c 354d 6576 8797
9fa4 a7a4 864b 252e 5973 7673 7b86 7e6d
6164 6c7a 8b98 a2ac b8bd ae96 857f 6d40
1d14 160b 0000 0000 0000 0000 0000 0000

, и мне нужно прочитать их и напечатать их значение int (0-255).Я пытаюсь это, но все результаты выглядят так: 0020 0a00 2000 2000 2000 2000 2000 2000 Я не знаю, что не так, fopen как бинарный файл в порядке?

FILE * pFile;
pFile = fopen(inFileName.c_str(), "rb");
if (pFile==NULL){
    cerr << "erro" << endl;
}

uint8_t bufferImmagine[height*width];
fread(bufferImmagine,1,height*width,pFile);

fclose (pFile);
for (int i = 0; i < height*width; ++i)
{
   cout << bufferImmagine[i] << " ";
}

Ответы [ 2 ]

0 голосов
/ 20 апреля 2019

Я вижу несколько потенциальных проблем с кодом:

1) Как уже упоминалось в комментариях, uint8_t bufferImmagine[height*width]; проблематично, поскольку C ++ не поддерживает массивы переменной длины, поэтому, если height и width не могут быть преобразованы в константы времени компиляции, это будет Вместо этого лучше использовать std::vector (или, если у вас аллергия на структуры данных, вы можете выделить массив с помощью оператора new, но тогда вы рискуете потерять память, если не будете очень осторожны).

2) В зависимости от значений width и height размер bufferImmagine может быть довольно большим; возможно, больше, чем объем доступного стекового пространства. Другая причина использовать std::vector или выделить в куче, вместо этого.

3) Вы никогда не проверяете возвращаемое значение вызова fread(), чтобы увидеть, прочитал ли он все данные или нет. Возможно, он читает меньше байтов, чем вы просили его прочитать (скорее всего, потому, что файл, который вы читаете, недостаточно длинный), но без проверки значения вы не узнаете, что что-то пошло не так, так что вы будете очень сбит с толку, если / когда происходит ошибка.

4) Как отметил Джек С. в своем ответе, cout может распечатывать uint8_t как символы ASCII, а не как целые числа, что здесь не то, что вам нужно.

5) На самом деле это не проблема, но если вы хотите, чтобы строки вашего вывода соответствовали строкам пикселей в вашем файле, тогда вы захотите применить возврат каретки в конце каждой строки. ». E.g.:

int i = 0;
for (int y = 0; y < height; y++)
{
   for (int x = 0; x < width; x++)
   {
      const unsigned int iVal = bufferImmagine[i];
      cout << iVal << " ";
      i++;
   }  
   cout << endl;
}  
0 голосов
/ 20 апреля 2019

Итак, bufferImmagine - это массив типа uint8_t, а на многих платформах uint8_t - это псевдоним unsigned char. Когда вы передаете unsigned char в std::cout, поток обрабатывает его как символ, а не число.

Если вы хотите распечатать каждый байт в виде числа 0-255, преобразуйте каждый байт в более широкий целочисленный тип, например unsigned:

std::cout << static_cast<unsigned int>(bufferImmagine[i]) << " ";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...