使用libgd将PNG转JPEG
直接上代码:
gdImagePtr loadImage(const char *name)
{
FILE *fp;
gdImagePtr im;
fp = fopen(name, "rb");
if (!fp) {
fprintf(stderr, "Can't open png file\n");
return NULL;
}
im = gdImageCreateFromPng(fp);
fclose(fp);
return im;
}
int saveJpegImage(gdImagePtr im, const char *name)
{
FILE *fp;
fp = fopen(name, "wb");
if (!fp) {
fprintf(stderr, "Can't save jpeg image \n");
return 0;
}
gdImageJpeg(im, fp);
fclose(fp);
return 1;
}
int main(int argc, char **arg)
{
gdImagePtr im;
im = loadImage("test.png");
if (!im) return 1;
saveJpegImage(im, "test.jpg");
return 0;
}
转换前的照片test.png
转换后的照片test.jpg
原因和解决方法
原因
png支持透明度和半透明度,所谓透明度就是alpha通道。png有4个通道:R通道、G通道、B通道、alpha通道。前3个通道表示RGB三色通道,alpha通道表示透明度。jepg只有3个通道:R通道、G通道、B通道,没有alpha通道,所以不支持透明度。
png转jpeg之前要移除alpha通道,透明区域默认被填充成了黑色。
解决方法
要想PNG的透明区域在转换格式时不被填充成黑色,可以创建同样大小的一个图,先全部填充为白色,最后在把PNG的像素复制过来。代码如下:
int main(int argc, char **arg)
{
gdImagePtr im, out_im;
im = loadImage("test.png");
if (!im) return 1;
out_im = gdImageCreateTrueColor(im->sx, im->sy);
gdImageFilledRectangle(out_im, 0, 0, im->sx, im->sy, 0xffffff);
gdImageCopy(out_im, im, 0, 0, 0, 0, im->sx, im->sy);
saveJpegImage(out_im, "test.jpg");
return 0;
}
参考:
https://stackoverflow.com/questions/57757439/how-to-convert-png-file-to-webp-file
https://stackoverflow.com/questions/3906260/how-can-i-convert-a-jpeg-image-to-a-png-one-with-transparent-background
https://stackoverflow.com/questions/2569970/gd-converting-a-png-image-to-jpeg-and-making-the-alpha-by-default-white-and-not