我对基本的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个问题:
答案 0 :(得分:1)
png_write_row
一次编写图像行,但它与png_write_image
应该大致相同。
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
int main(){
png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
exit (EXIT_FAILURE);
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, NULL);
exit (EXIT_FAILURE);
}
if(setjmp(png_jmpbuf(png_ptr))){
printf ("PNG error\n");
exit(EXIT_FAILURE);
}
FILE * fp = fopen("foo.png", "wb");
if(fp==NULL){
perror("opening output file");
exit (EXIT_FAILURE);
}
png_init_io(png_ptr, fp);
int width=100, height=100;
png_set_IHDR(png_ptr,
info_ptr,
width,
height,
8, // bit_depth,
PNG_COLOR_TYPE_PALETTE,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
png_color palette[] = {
{0,0,0}, {100,0,0}
};
png_set_PLTE(png_ptr, info_ptr, palette, 2);
png_byte trans[] = {255, 128}; // entry 0 opaque, entry 1 half alpha
png_set_tRNS(png_ptr, info_ptr, trans, 2, NULL);
png_write_info(png_ptr, info_ptr);
// write the image data, row by row
for (int y=0; y<height; y++) {
png_byte row[width];
for (int x = 0; x < width; x++){
row[x] = ((50-x)*(50-x) + (50-y)*(50-y)) < (50*50); // circle
}
png_write_row(png_ptr, row);
}
png_write_end(png_ptr, NULL);
png_destroy_write_struct(&png_ptr, &info_ptr);
png_free(png_ptr, palette);
return 0;
}
请注意,仅为我的调试,palette[1]
(非透明条目)设置为red-ish。听起来你为了你的目的将它设置为黑色。