libpng 输出不是预期的输出
libpng output is not the expected one
我正在尝试掌握 libpng 的基本功能。为此,我使用了 this snippet 并适应了我自己的示例。
int x, y;
png_byte color_type = PNG_COLOR_TYPE_RGBA;
png_byte bit_depth = 16;
png_structp png_ptr;
png_infop info_ptr;
auto create_image(const int height, const int width) {
png_byte **rows = new png_byte *[height];
for (auto i = 0; i < height; i++)
rows[i] = new png_byte[width * 4];
return rows;
}
auto modify_image(const int height, const int width, png_byte **rows) {
for (auto i = 0; i < height; i++) {
for (auto j = 0; j < width; j++) {
// Red channel
rows[i][j * 4 + 0] = (j * 127.) / width;
// Blue channel
rows[i][j * 4 + 2] = (i * 127.) / height;
// Alpha channel
rows[i][j * 4 + 3] = 127;
}
}
}
void write(const std::string& filename, const int height, const int width, png_byte** rows)
{
/* create file */
FILE *fp = fopen(filename.c_str(), "wb");
if (!fp)
abort_("[write_png_file] File %s could not be opened for writing", filename);
/* initialize stuff */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
abort_("[write_png_file] png_create_write_struct failed");
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
abort_("[write_png_file] png_create_info_struct failed");
if (setjmp(png_jmpbuf(png_ptr)))
abort_("[write_png_file] Error during init_io");
png_init_io(png_ptr, fp);
/* write header */
if (setjmp(png_jmpbuf(png_ptr)))
abort_("[write_png_file] Error during writing header");
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
/* write bytes */
if (setjmp(png_jmpbuf(png_ptr)))
abort_("[write_png_file] Error during writing bytes");
png_write_image(png_ptr, rows);
/* end write */
if (setjmp(png_jmpbuf(png_ptr)))
abort_("[write_png_file] Error during end of write");
png_write_end(png_ptr, NULL);
fclose(fp);
}
不过,当我 运行 我的代码时:
void render(const int height, const int width, const std::string &filename) {
png_byte **rows = create_image(height, width);
modify_image(height, width, rows);
write(filename, height, width, rows);
}
问题是...我根本没有得到预期的结果。当我期待一个带有某种渐变的正方形图像时,我得到了......两个矩形矩形。
另外,我注意到这两个矩形被拉伸了:在尝试渲染一个圆时,我发现圆被扭曲了,将其宽度加倍使其成为一个真正的圆...
最后,我看到在第二个矩形上,最后一行似乎是随机数据(在第一个矩形上不是这种情况)。
有什么想法请提出来
您创建了 16 位深度的图像,但每个通道使用 1 个字节。输出图像由放置在同一行的原始图像的奇数/偶数行组成。基本上右边矩形的每一行都是由缓冲区溢出引起的。您需要分配两倍大的缓冲区,即 width * 4 * 2
并分别填充每个通道的高字节和低字节。
我正在尝试掌握 libpng 的基本功能。为此,我使用了 this snippet 并适应了我自己的示例。
int x, y;
png_byte color_type = PNG_COLOR_TYPE_RGBA;
png_byte bit_depth = 16;
png_structp png_ptr;
png_infop info_ptr;
auto create_image(const int height, const int width) {
png_byte **rows = new png_byte *[height];
for (auto i = 0; i < height; i++)
rows[i] = new png_byte[width * 4];
return rows;
}
auto modify_image(const int height, const int width, png_byte **rows) {
for (auto i = 0; i < height; i++) {
for (auto j = 0; j < width; j++) {
// Red channel
rows[i][j * 4 + 0] = (j * 127.) / width;
// Blue channel
rows[i][j * 4 + 2] = (i * 127.) / height;
// Alpha channel
rows[i][j * 4 + 3] = 127;
}
}
}
void write(const std::string& filename, const int height, const int width, png_byte** rows)
{
/* create file */
FILE *fp = fopen(filename.c_str(), "wb");
if (!fp)
abort_("[write_png_file] File %s could not be opened for writing", filename);
/* initialize stuff */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
abort_("[write_png_file] png_create_write_struct failed");
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
abort_("[write_png_file] png_create_info_struct failed");
if (setjmp(png_jmpbuf(png_ptr)))
abort_("[write_png_file] Error during init_io");
png_init_io(png_ptr, fp);
/* write header */
if (setjmp(png_jmpbuf(png_ptr)))
abort_("[write_png_file] Error during writing header");
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
/* write bytes */
if (setjmp(png_jmpbuf(png_ptr)))
abort_("[write_png_file] Error during writing bytes");
png_write_image(png_ptr, rows);
/* end write */
if (setjmp(png_jmpbuf(png_ptr)))
abort_("[write_png_file] Error during end of write");
png_write_end(png_ptr, NULL);
fclose(fp);
}
不过,当我 运行 我的代码时:
void render(const int height, const int width, const std::string &filename) {
png_byte **rows = create_image(height, width);
modify_image(height, width, rows);
write(filename, height, width, rows);
}
问题是...我根本没有得到预期的结果。当我期待一个带有某种渐变的正方形图像时,我得到了......两个矩形矩形。
另外,我注意到这两个矩形被拉伸了:在尝试渲染一个圆时,我发现圆被扭曲了,将其宽度加倍使其成为一个真正的圆...
最后,我看到在第二个矩形上,最后一行似乎是随机数据(在第一个矩形上不是这种情况)。
有什么想法请提出来
您创建了 16 位深度的图像,但每个通道使用 1 个字节。输出图像由放置在同一行的原始图像的奇数/偶数行组成。基本上右边矩形的每一行都是由缓冲区溢出引起的。您需要分配两倍大的缓冲区,即 width * 4 * 2
并分别填充每个通道的高字节和低字节。