C 如何使用选项板设置libpng背景透明度?
我对libpng的基本概念缺乏理解,所以请容忍我。我有以下源代码:C 如何使用选项板设置libpng背景透明度?,c,libpng,C,Libpng,我对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 mai
#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);
}
#包括
#包括
#包括
void cb(){printf(“callbacked\n”);}
//写行
void wr_cb(png_structp png_ptr,png_uint_32行,int pass){
//printf(“wr cb”);
}
int main(){
文件*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*调色板=(png_color*)png_malloc(png_ptr,2*sizeof(png_color));
png_字节*行指针;
png_color_16 bgcolor;
bgcolor.red=255;
bgcolor.green=255;
bgcolor.blue=255;
//调色板[]
png_color*c1=&调色板[0];
png_color*c2=&调色板[1];
c1->红色=255;c1->绿色=255;c1->蓝色=255;
c2->红色=0;c2->绿色=0;c2->蓝色=0;
if(setjmp(png_jmpbuf(png_ptr))){
png_destroy_write_struct(&png_ptr和&info_ptr);
fclose(fp);
printf(“错误:已销毁所有\n”);
}
png_init_io(png_ptr,fp);
png设置写入状态(png ptr、wr cb);
png设置压缩级别(png ptr、Z最佳压缩);
png\u设置\u IHDR(png\u ptr、info\u ptr、500、500、1、png\u颜色类型\u调色板、png\u交错\u无、png\u压缩类型\u默认、png\u过滤器类型\u默认);
png_集_PLTE(png_ptr,信息_ptr,调色板,2);
png_write_info(png_ptr,info_ptr);
行指针=(png_bytep*)malloc(500*sizeof(png_bytep));
对于(size_t l=0;l<500;l++){
行指针[l]=(png_字节*)malloc(png_get_行字节(png_ptr,info_ptr));
//png_get_rowbytes(png_ptr,info_ptr)->给出63
如果(l==10)
对于(大小k=0;k<70;k++){//NOTE\u
行指针[l][k]=150;//255-画一条线
}
}
png_设置_背景(png_ptr,c2,png_背景_GAMMA_屏幕,0,1);
png_写入_图像(png_ptr,行指针);
png_write_end(png_ptr,info_ptr);
png_destroy_write_struct(&png_ptr和&info_ptr);
png_免费(png_ptr,调色板);
}
我用gcc thefile.c-lpng-opng\u生成器编译它
运行png_maker会显示以下图像:
我使用PNG_颜色_类型_调色板,因为我希望只使用两种颜色-我的假设是使用调色板将生成比不使用调色板更小的PNG文件-因为在我的用例中,我在图片中只需要两种像素颜色:黑色或白色/透明-这一假设正确吗
3个问题:
嗯,我的设置代码和你的非常相似。我使用
png\u write\u row
一次写入图像行,但是它应该与png\u write\u 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;
}
#包括
#包括
#包括
int main(){
png_structp png_ptr=png_create_write_struct(png_LIBPNG_VER_STRING,NULL,NULL,NULL);
如果(!png_ptr){
退出(退出失败);
}
png_infop info_ptr=png_create_info_struct(png_ptr);
如果(!info_ptr){
png_destroy_write_struct(&png_ptr,NULL);
退出(退出失败);
}
if(setjmp(png_jmpbuf(png_ptr))){
printf(“PNG错误\n”);
退出(退出失败);
}
文件*fp=fopen(“foo.png”、“wb”);
如果(fp==NULL){
perror(“打开输出文件”);
退出(退出失败);
}
png_init_io(png_ptr,fp);
内部宽度=100,高度=100;
png\U set\U IHDR(png\U ptr,
信息,
宽度,
高度,
8,//位深度,
PNG_颜色_类型_调色板,
PNG\u交错\u无,
PNG_压缩_类型_基础,
PNG_过滤器_类型_底座);
png_调色板[]={
{0,0,0}, {100,0,0}
};
png_集_PLTE(png_ptr,信息_ptr,调色板,2);
png_byte trans[]={255,128};//条目0不透明,条目1半字母
png_集_tRNS(png_ptr,info_ptr,trans,2,NULL);
png_write_info(png_ptr,info_ptr);
//逐行写入图像数据
对于(int y=0;我接受了你的答案,因为它给了我一些工作的依据。但是从你的代码中,我看到你在做行[x]=0或1
-表示有颜色的像素,而1、0表示透明。如何从调色板中为像素提供有关颜色的数据?您的代码使用的是正确的颜色,但为什么?行[x]=0或1
表示使用调色板条目0
或1
,其颜色和透明度决定像素的颜色和透明度。我关于设置条目透明度的代码很差-我已经替换了关于trans的两行,这两行应该更清晰。特定调色板条目的颜色在epalette
array:png_调色板[]={{0,0,0}、{100,0,0};#黑色、红色
适用于可能遇到相同问题的人。根据规范,如果你对颜色使用palette,你就必须使用TRN来实现透明度。“PNG规范禁止对基于调色板的图像使用完整的alpha通道,但它确实允许通过透明块tRNS使用‘廉价alpha’。”