Преобразовать цветное изображение в черно-белое - C (СИ)
Формулировка задачи:
Интересует не вычисление порога, и не алгоритм.
В c# я загружаю изображение в bitmap, лочу, загружаю через marshal copy в память, редактирую байты в массиве , унлочу.
А как эту задачу решить в си?
Решение задачи: «Преобразовать цветное изображение в черно-белое»
textual
Листинг программы
#include <stdio.h> #include <malloc.h> #include <stdint.h> //только для 24/32-битных растров int bmp_to_gray(const char* fn){ int bpp, width, height, r, g, b; long off; size_t num, size, i; uint8_t* bits, *pb; uint16_t finf[7]; uint32_t inf[10]; FILE* fp = fopen(fn, "rb+"); if(fp == NULL) return 0; num = fread((void*)&finf[0], sizeof(finf[0]), 7, fp); if((finf[0] != 0x4D42) || (num != 7)){ fclose(fp); return 0; } num = fread((void*)&inf[0], sizeof(inf[0]), 10, fp); bpp = (int)((inf[3] >> 16) & 0xFFFF); if((inf[4] != 0) || (bpp < 24) || (bpp > 32) || (num != 10)){ fclose(fp); return 0; } off = (long)((uint32_t)finf[6] << 16) | finf[5]; fseek(fp, off, SEEK_SET); if(feof(fp)){ fclose(fp); return 0; } width = (int)inf[1]; height = (int)inf[2]; if(height < 0) height = 0 - height; size = (size_t)((width * bpp + 31) & ~31) / 8 * height; bits = (uint8_t*)malloc(size); if(bits == NULL){ fclose(fp); return 0; } num = fread((void*)bits, 1, size, fp); if(num != size){ fclose(fp); free(bits); return 0; } bpp /= 8; pb = bits; for(i = 0; i < size; i += bpp){ r = (int)pb[0]; g = (int)pb[1]; b = (int)pb[2]; pb[0] = (uint8_t)((r * 77 + g * 150 + b * 29 + 128) / 256); pb[1] = pb[0]; pb[2] = pb[0]; pb += bpp; } fseek(fp, off, SEEK_SET); num = fwrite((const void*)bits, 1, size, fp); fflush(fp); fclose(fp); free(bits); if(num != size) num = 0; return (num > 0); } int main(void) { if(bmp_to_gray("image.bmp")) puts("yes to gray."); else puts("error convert!"); return 0; }
Объяснение кода листинга программы
Вот что делает этот код:
- Открывает файл изображения. Функция
fopen
используется для открытия файла с именемimage.bmp
в режиме чтения (rb+
). Если файл не может быть открыт, функция возвращает NULL. - Проверяет, является ли файл изображением BMP. Функция
fread
используется для чтения первых 7 байтов файла. Затем проверяется, являются ли первые 2 байта (код файла) равными 0x4D42 (BMP). Если это не так или чтение не удалось, файл закрывается и возвращается 0. - Проверяет, является ли файл 24- или 32-битным изображением. Функция
fread
используется для чтения следующих 10 байтов файла. Затем извлекаются следующие 3 байта (информация о глубине цвета) и проверяются. Если глубина цвета не равна 24 или 32, файл закрывается и возвращается 0. - Находит смещение данных изображения. Следующие 2 байта (информация о размере) считываются и используются для вычисления смещения данных изображения.
- Считывает данные изображения и преобразует их в оттенки серого. Функция
fread
используется для считывания данных изображения. Затем данные перебираются, и для каждого пикселя вычисляется средний цвет (красный, зеленый и синий пиксели считаются одинаковыми). Этот средний цвет затем записывается обратно в файл. - Закрывает файл и проверяет успешность операции. Функция
fclose
используется для закрытия файла. Затем проверяется, удалось ли записать данные в файл (возвращаетсяfwrite
). Если операция не удалась, файл открывается заново и возвращается 0. - Выводит сообщение об успехе или ошибке. В функции
main
выводится сообщениеyes to gray.
илиerror convert!
, в зависимости от того, вернула ли функцияbmp_to_gray
значение больше 0.