Я пытаюсь пикселировать изображение в формате P6 PPM, выполнив следующие действия:
- Чтение изображения PPM в сетках 4x4
- Найти среднее значение цвета RGB для каждой сетки 4x4
- Записать в новый файл , установив для каждой сетки 4x4 пикселей в новом изображении среднее значение цвета RGB.
Файл PPM начинается в следующем формате:
P6
# ignores comments in header
width
height
max colour value
Моя проблема:
Выходной файл изображения PPM (который я открываю с помощью редактора изображений GIMP, а также может быть открыт в любом текстовом редакторе, таком как Блокнот для просмотра необработанных данных) состоит из одного плоского цветового блока, когда вместо этого он должен напоминать своего рода мозаику.
Примечание: Сетка 4x4 может быть изменена, т. Е. Чем больше значение размеров сетки, тем более пикселируется выходное изображение. На мой код больше всего повлиял другой вопрос переполнения стека, где пользователь пытался сделать аналогичную реализацию в C #. Ссылка на этот вопрос:
https://codereview.stackexchange.com/questions/140162/pixelate-image-with-average-cell-color
ОБНОВЛЕНИЕ: Вывод теперь, кажется, пикселирует первую 1/5 изображения, но остальная часть выходного изображения остается одним цветным блоком. Я думаю, что моя проблема заключается в том, что я рассматриваю клетки как пиксели в линейном порядке.
Моя попытка:
#include <stdio.h>
#include <assert.h>
//Struct to store RGB values
typedef struct {
unsigned char r, g, b;
} pixel;
int main()
{
int y, x; //Loop iteration variables
int yy = 0; //Loop iteration variables
int xx = 0; //Loop iteration variables
char magic_number[10]; //Variable which reads P6 in the header
int w, h, m; //Image dimension variables
pixel currentPix; //Current pixel variable
int avR; //Red declaration
int avG; //Green declaration
int avB; //Blue declarataion
int total; //Loop iteration counter declaration
//Input file
FILE* f;
f = fopen("Dog2048x2048.ppm", "r"); //Read PPM file
if (f == NULL) //Error notifiaction if file cannot be found
{
fprintf(stderr, "ERROR: cannot open input file");
getchar();
exit(1);
}
//Scan the header of the PPM file to get the magic number (P6), width
//height and max colour value
fscanf(f, "%s %d %d %d", &magic_number, &w, &h, &m);
//initialize file for writing (open and header)
FILE* f_output;
f_output = fopen("some_file.ppm", "w");
//fprintf(f_output, "%s %d %d %d", magic_number, w, h, m);
fprintf(f_output, "P6\n%d %d\n255\n", w, h);
if (f_output == NULL) //Error notifiaction if file cannot be found
{
fprintf(stderr, "ERROR: cannot open output file");
getchar();
exit(1);
}
// Loop through the image in 4x4 cells.
for (int yy = 0; yy < h && yy < h; yy += 4)
{
for (int xx = 0; xx < w && xx < w; xx += 4)
{
avR = 0;
avG = 0;
avB = 0;
total = 0;
// Store each color from the 4x4 cell into cellColors.
for (int y = yy; y < yy + 4 && y < h; y++)
{
for (int x = xx; x < xx + 4 && x < w; x++)
{
//Reads input file stream
fread(¤tPix, 3, 1, f);
//Current pixels
avR += currentPix.r;
avG += currentPix.g;
avB += currentPix.b;
//Counts loop iterations for later use in colour averaging
total++;
}
}
//Average RGB values
avR /= total;
avG /= total;
avB /= total;
// Go BACK over the 4x4 cell and set each pixel to the average color.
for (int y = yy; y < yy + 4 && y < h; y++)
{
for (int x = xx; x < xx + 4 && x < w; x++)
{
//Print out to new file
fprintf(f_output, "%i %i %i\t", avR, avG, avB);
}
}
}
fprintf(f_output, "\n");
}
return 0;
}