提问人:Adam 提问时间:10/23/2023 最后编辑:Adam 更新时间:10/23/2023 访问量:85
如何将rgb颜色正确保存到ppm文件?
How to save rgb color to ppm file properly?
问:
我尝试制作简单的 c 程序,将 rgb 颜色保存到 ppm 文件 usinf 1D 数组。这是一个教育项目
#include <complex.h>
#include <math.h>
#include <omp.h> //OpenM
#include <stdio.h>
#include <stdlib.h>
/*
fork of
mandelbrot-book how to write a book about the Mandelbrot set by Claude
Heiland-Alle https://code.mathr.co.uk/mandelbrot-book/blob/HEAD:/book/
https://stackoverflow.com/questions/77135883/why-do-my-functions-not-work-in-parallel
gcc c.c -lm -Wall -fopenmp
./a.out > rgb.ppm // P6 = binary Portable PixMap see
https://en.wikipedia.org/wiki/Netpbm#File_formats
convert rgb.ppm rgb.png
*/
double aspect_ratio = 16.0 / 9.0; // = w/h
const int h = 200;
int w; // = h * aspect_ratio;
const double r = 2.0; // plane radius
const double px = r / (h / 2);
double width;
double xMin;
// https://stackoverflow.com/questions/2594913/getting-the-fractional-part-of-a-float-without-using-modf
double frac(double d) { return d - (int)d; }
// rgb in [0,1] range
void giveRGBColor(const complex double z, double *r, double *g, double *b) {
*r = frac(abs((creal(z) - xMin)) / width); //
*g = 1.0;
*b = 1.0;
}
int main() {
w = h * aspect_ratio; // The aspect ratio of an image is the ratio of its
// width to its height, and is expressed with two
// numbers separated by a colon, such as 16:9,
unsigned char *img = malloc(3 * w * h); // image
width = r * 2.0 * aspect_ratio;
double height = r * 2.0;
xMin = (0 + 0.5 - w / 2) / (h / 2) * r;
fprintf(stderr, "image width = %.2f in world coordinate\n", width);
fprintf(stderr, "image height = %.2f in world coordinate\n", height);
fprintf(stderr, "image aspect ratio = width:height = %d:%d = %f = %f = %f\n",
w, h, w / (1.0 * h), width / (1.0 * height), aspect_ratio);
#pragma omp parallel for schedule(dynamic)
for (int j = 0; j < h; ++j) {
double y = (h / 2 - (j + 0.5)) / (h / 2) * r;
for (int i = 0; i < w; ++i) {
double x = (i + 0.5 - w / 2) / (h / 2) * r; // for q=2 add -0.5
double _Complex z = x + I * y;
// color
double red, grn, blu;
giveRGBColor(z, &red, &grn, &blu); // compute rgb
// convert to [0,255] integer and save rgb color to array
img[3 * (j * w + i) + 0] = (int)(255 * red);
img[3 * (j * w + i) + 1] = (int)(255 * grn);
img[3 * (j * w + i) + 2] = (int)(255 * blu);
}
}
//
printf("P6\n%d %d\n255\n", w, h);
fwrite(img, 3 * w * h, 1, stdout);
free(img);
return 0;
}
答:
3赞
AKX
10/23/2023
#1
将您的程序削减到实际的最低限度,并更改计算方式和计算方式以显示您想要的效果(嗯,也多一点,在另一个轴上有一个黑色到蓝色的渐变):red
blu
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
double aspect_ratio = 16.0 / 9.0;
int h = 200;
int w = h * aspect_ratio;
unsigned char *img = malloc(3 * w * h); // image
for (int j = 0; j < h; ++j) {
for (int i = 0; i < w; ++i) {
double red = i / (double)w, grn = 0, blu = j / (double)h;
// convert to [0,255] integer and save rgb color to array
img[3 * (j * w + i) + 0] = (int)(255 * red);
img[3 * (j * w + i) + 1] = (int)(255 * grn);
img[3 * (j * w + i) + 2] = (int)(255 * blu);
}
}
printf("P6\n%d %d\n255\n", w, h);
fwrite(img, 3 * w * h, 1, stdout);
free(img);
return 0;
}
这将产生以下图像:
换句话说,我们可以说你的 PPM 编写代码是绝对没问题的。
评论
0赞
Adam
10/23/2023
感谢。您的程序更短且有效。你能告诉我我的程序中的错误吗?
0赞
Adam
10/23/2023
#2
我发现了我的错误。我想要单色 1d 颜色渐变,但我已将其他颜色通道设置为 1 而不是 0。
评论
giveRGBColor()
*r = 1; *g = *b = frac(abs((creal(z) - xMin)) / width);
*g = 1.0
*b = 1.0