Есть ли способ прочитать пиксели изображения или любые данные с учетом изображения с помощью FILE fopen в C? Меня не интересуют библиотеки. Я попытался прочитать данные изображения с помощью fgetc, но он распечатывает некоторые числа, которые не имеют никакого смысла.

РЕДАКТИРОВАТЬ: Я знаю, что он должен распечатывать числа, но я ожидал, что числа представляют каждый пиксель.

РЕДАКТИРОВАТЬ: Я ищу ссылки на документацию, которые помогут мне понять, как форматы jpeg или png работают и хранят данные.

0
Trailblazer17 15 Окт 2021 в 10:13

3 ответа

Лучший ответ

Если вы действительно хотите иметь возможность читать и записывать изображения, просто с помощью указателя FILE, вам нужно посмотреть на формат файла, называемый .ppm. (Portable Pixel Map.) Это, конечно, предполагает, что вы можете конвертировать файлы изображений в .ppm, но это легко сделать с помощью инструмента командной строки imagemagick. Вы можете использовать imagemagick для преобразования .ppms, которые вы пишете, в любой тип вывода, который вам нравится.

Формат безумно прост:

  • Начинается с двух символов («магическое число») «P6».
  • После P6 следует пробел, а затем ширина (в ascii) изображения.
  • За шириной следует пробел, а затем - высота (в ascii) изображения.
  • Последний бит заголовка - это «максимальное значение» записи. Просто используйте 255. После этого укажите пробел.
  • После этого вы просто записываете в двоичном формате значения RGB. Один беззнаковый символ на канал.

Примере:

P6 128 128 255
[128 * 128 * 3 bytes of data go here, in row major order. The top-left 
 pixel is first, then the pixel to the right of it. When you get to the 
 end of a row, just write the first pixel of the next row. That's all 
 there is. No other header info, no terminators, etc.]

Примере:

#include <stdio.h>
void main() {
  FILE * out;
  out = fopen("color_test.ppm", "wb");
  fprintf(out, "P6 256 256 255\n");
  for(int r=0; r<256; r++) {
    for(int b=0; b<256; b++) {
      fputc(r, out);
      fputc(0, out);
      fputc(b, out);
    }
  }
  fclose(out);
}

Это порождает:

Image with reds in the vertical (0 at top and 255 at bottom) and blues along the bottem, with 0 at the left.

Чтение файлов также легко. Вы можете просто вытащить их в трехмерный массив беззнаковых символов, манипулировать ими в памяти, как вам нравится, а затем записать эти данные обратно в другой файл, как это делает мой пример.

1
Sniggerfardimungus 15 Окт 2021 в 07:58

Вы можете читать изображения без использования библиотек, но это большая работа.

Например, libjpeg-turbo, вероятно, самая популярная библиотека для чтения изображений JPEG:

https://github.com/libjpeg-turbo/libjpeg-turbo

Это около 50 000 строк языка C и сборки.

Интересно, что он включает функции для чтения и записи некоторых других форматов (эти процедуры используются инструментами командной строки JPEG для преобразования формата файлов). Например, вот код, используемый libjpeg-turbo для загрузки изображения BMP:

https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/rdbmp.c

Около 700 строк, хотя он может читать только подмножество BMP.

0
jcupitt 15 Окт 2021 в 08:53

Я не совсем понимаю, что вы хотите сделать, но язык C - это язык программирования низкого уровня. Конечно, в памяти не останется ничего, кроме цифр.

Самый простой способ сохранить изображение в C - создать матричную структуру и сохранить значения RGB. Указанные числа могут быть значениями RGB каждого пикселя.

0
Ersin Öztürk 15 Окт 2021 в 07:49