【发布时间】:2018-09-22 17:28:29
【问题描述】:
我对基本的 libpng 概念缺乏了解,所以请耐心等待。我有以下源代码:
#include <png.h>
#include <stdio.h>
#include <stdint.h>
void cb() { printf("callbacked\n"); }
// write row
void wr_cb (png_structp png_ptr, png_uint_32 row, int pass) {
//printf("wr cb");
}
int main(){
FILE *fp = fopen("pic.png", "wb");
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp) cb, cb, cb);
png_infop info_ptr = png_create_info_struct(png_ptr);
png_color* palette = (png_color*) png_malloc(png_ptr, 2*sizeof(png_color));
png_bytep* row_pointers;
png_color_16 bgcolor;
bgcolor.red = 255;
bgcolor.green =255;
bgcolor.blue = 255;
//palette[]
png_color *c1 = &palette[0];
png_color *c2 = &palette[1];
c1->red=255; c1->green=255; c1->blue=255;
c2->red=0; c2->green= 0; c2->blue= 0;
if (setjmp(png_jmpbuf(png_ptr))){
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
printf("error: destroyed all\n");
}
png_init_io(png_ptr, fp);
png_set_write_status_fn(png_ptr, wr_cb);
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
png_set_IHDR(png_ptr, info_ptr, 500, 500, 1, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_set_PLTE(png_ptr,info_ptr, palette, 2);
png_write_info(png_ptr, info_ptr);
row_pointers = (png_bytep*) malloc(500*sizeof(png_bytep));
for (size_t l = 0; l < 500; l ++){
row_pointers[l]= (png_byte*) malloc( png_get_rowbytes(png_ptr, info_ptr));
//png_get_rowbytes(png_ptr, info_ptr) -> gives 63
if (l==10)
for (size_t k = 0; k < 70; k++){// NOTE_HERE
row_pointers[l][k] =150; // 255 - draws a line
}
}
png_set_background(png_ptr, c2, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1);
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
png_free(png_ptr, palette);
}
我用 gcc thefile.c -lpng -o png_maker 编译它 运行 png_maker 会得到以下图像:
我正在使用 PNG_COLOR_TYPE_PALETTE,因为我希望只使用两种颜色 - 我的假设是使用调色板会生成比不使用调色板更小的 png 文件 - 因为在我的用例中,我只需要两种像素颜色图片中:黑色或白色/透明 - 这个假设是否正确?
3 个问题:
- 从图中可以看到顶部有黑色虚线。但是没有透明度。
- 在第二个 for 循环中(在代码中查找“NOTE_HERE”)。我正在检查 k 是否小于 70(用于测试的硬编码数字,因为给它更大的数字我会得到 SIGSEGV)。 png_byte 是 unsigned char 的 typedef。所以我的猜测是 png_get_row_bytes 给它 63 个字节,我猜现在它使用 1 位来表示 1 个像素?如果是这样,我该如何设置?
- 如何将调色板中的颜色分配给某个点的像素?
【问题讨论】:
-
对于那些可能遇到同样问题的人。似乎如果您使用调色板作为颜色,则必须使用 tRNS 来实现透明度 - 根据规范。 “PNG 规范禁止对基于调色板的图像使用完整的 alpha 通道,但它确实允许通过透明度块 tRNS 实现‘便宜的 alpha’。”来自:libpng.org/pub/png/book/chapter08.html