dlinyj
@dlinyj

Формирование 16-битного PGM-файла

Решил я для экспериментов с поверхностями представить онные в виде графических файлов (большое спасибо за идею Eddy_Em. Для этого взял отличный простой формат файла PGM. Описание формата. С 8-ми битным форматом вообще всё отлично работает:

#include <stdio.h>
#define width 255
#define height 255
int main()
{
	unsigned int i,j;
	FILE *img_file = NULL;
	img_file = fopen("dat/greyscale.pgm", "w");
	char tmp=0;
	fprintf(img_file, "P5 \n%d %d \n255 \n", width, height);
	for (i = 0; i < width; i++) {
		for (j = 0; j < height; j++) {
			tmp=i;
			fwrite(&tmp, sizeof(char), 1, img_file);
		}
	}
	if (img_file != NULL) 	fclose(img_file);
	return 0;
}


Результат отличный. Размер выходного файла 65 043 байта



Но стоит попробовать перейти на двухбайтовый формат, всё идёт лесом.
Заменяю переменную с данными на short

unsigned short tmp=0;


В заголовке файла говорю о том, что у нас теперь значащих 16 бит:
fprintf(img_file, "P5 \n%d %d \n65535 \n", width, height);


И пишу теперь уже short

fwrite(&tmp, sizeof(unsigned short), 1, img_file);


Полный вариант кода
#include <stdio.h>

#define width 255
#define height 255
int main()
{
	unsigned int i,j;
	FILE *img_file = NULL;
	img_file = fopen("dat/greyscale.pgm", "w");
	unsigned short tmp=0;
	fprintf(img_file, "P5 \n%d %d \n65535 \n", width, height);
	for (i = 0; i < width; i++) {
		for (j = 0; j < height; j++) {
			tmp=i;
			fwrite(&tmp, sizeof(unsigned short), 1, img_file);
		}
	}
	if (img_file != NULL) 	fclose(img_file);
	return 0;
}



Получаю ошибочный файл, размером 130 070 байт, при открытии выглядящий как чёрный квадрат. HEX-редактор показывает, что в результате всё верно.

Даже если порядок байт не верный, всё равно должен быть на выходе не чёрный квадрат, а таки какой-то перелив.

Что делать и кто виноват? Как мне сформировать 16-битный grayscale файл? Может использовать какой другой несжатый формат (если да, то какой?).

UPD Проблема была решена следующим образом, вывод в файл был реализован строго-типизированно

{
			 tmp=(char)(i&0xFF);
			 fwrite(&tmp, sizeof(char), 1, img_file);
			 tmp=(char)((i>>8)&0xFF);
			 fwrite(&tmp, sizeof(char), 1, img_file);
}

Результирующий файл графические редакторы показывают чёрным, но работать с ним уже можно и БПФ делается…
  • Вопрос задан
  • 3862 просмотра
Решения вопроса 1
@Eddy_Em
Если ты хочешь хранить в графическом файле точные данные, очень советую тебе воспользоваться FITS-форматом!
Отличное описание + примеры работы с cfitsio лежат на просторах интернета. Ну и я сам нескромно могу предложить почитать мою ЖЖшку на этот счет.

Если же FITS'ы не нравятся, можно выбрать tiff (возможно даже со сжатием) или png. Я с обоими форматами работал: все отлично, никаких сложностей нет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы