gpt4 book ai didi

c++ - LibPng 背景

转载 作者:行者123 更新时间:2023-11-30 04:22:05 27 4
gpt4 key购买 nike

好的,所以在 photoshop 中,我创建了一个具有透明背景和一些文本的 8 位彩色图像。然后我创建了一个具有透明背景和一些文本的 16 位颜色的图像。

当我右键单击两个图像并转到属性时,它显示两个图像都是 32 位深度 :l所以我决定使用以下设置使用 LibPng 读取图像:

typedef union RGB     //Holds all the pixels..
{
uint32_t Color;
struct
{
unsigned char B, G, R, A;
} RGBA;
} *PRGB;


channels = png_get_channels(PngPointer, InfoPointer);
png_get_IHDR(PngPointer, InfoPointer, &width, &height, &bitdepth, &colortype, &interlacetype, nullptr, nullptr);
png_set_interlace_handling(PngPointer);
png_set_strip_16(PngPointer);
png_set_packing(PngPointer);

switch (colortype)
{
case PNG_COLOR_TYPE_GRAY:
{
png_set_expand_gray_1_2_4_to_8(PngPointer);
png_set_expand(PngPointer);
png_set_bgr(PngPointer);
break;
}

case PNG_COLOR_TYPE_PALETTE:
{
png_set_palette_to_rgb(PngPointer);
if (png_get_valid(PngPointer, InfoPointer, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(PngPointer);
png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);
png_set_bgr(PngPointer);
BitsPerPixel = 24;
break;
}

case PNG_COLOR_TYPE_GRAY_ALPHA:
{
png_set_gray_to_rgb(PngPointer);
break;
}

case PNG_COLOR_TYPE_RGB:
{
png_set_bgr(PngPointer);
png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);
BitsPerPixel = 24;
break;
}

case PNG_COLOR_TYPE_RGBA:
{
png_set_bgr(PngPointer);
BitsPerPixel = 32;
break;
}

default: png_destroy_read_struct(&PngPointer, &InfoPointer, nullptr); throw std::runtime_error("Error: Png Type not supported."); break;
}

//SET BACKGROUND
/*png_color_16 my_background, *image_background;
my_background.red = 255;
my_background.green = 255;
my_background.blue = 255;
image_background = &my_background;

if (png_get_bKGD(PngPointer, InfoPointer, &image_background))
{
png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);
png_set_background(PngPointer, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
}
else
{
png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);
png_set_background(PngPointer, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}*/
//END SET BACKGROUND

png_read_update_info(PngPointer, InfoPointer);
channels = png_get_channels(PngPointer, InfoPointer);
png_get_IHDR(PngPointer, InfoPointer, &width, &height, &bitdepth, &colortype, &interlacetype, nullptr, nullptr);

我的保存设置是:

png_set_write_fn(PngPointer, reinterpret_cast<void*>(&hFile), WriteToStream, nullptr);
png_set_IHDR (PngPointer, InfoPointer, width, height, bitdepth, BitsPerPixel == 24 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(PngPointer, InfoPointer);

png_set_bgr(PngPointer);
png_set_packing(PngPointer);
png_set_interlace_handling(PngPointer);
if (colortype == PNG_COLOR_TYPE_RGB) png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);

PNG 看起来像: enter image description here

当我通过 C++ 将它保存为位图时,它看起来像(8 位的一个这样做):enter image description here

将其另存为 PNG,它看起来与原始文件完全一样。 8 和 16 都可以保存回来。

问题是,如果我取消注释“SetBackground”部分,它可以完美地保存为位图,除了当我将它保存回 PNG 时,背景不再透明,因为代码将它设置为白色 (255, 255 , 255).

我该如何解决这个问题?

最佳答案

我对您的代码进行了一些更改。 未经测试!

channels = png_get_channels(PngPointer, InfoPointer);
png_get_IHDR(PngPointer, InfoPointer, &width, &height, &bitdepth, &colortype, &interlacetype, nullptr, nullptr);
png_set_interlace_handling(PngPointer);
png_set_strip_16(PngPointer);
png_set_packing(PngPointer);
bool BGneeded = (colortype > PNG_COLOR_TYPE_PALETTE);
switch (colortype)
{
case PNG_COLOR_TYPE_GRAY:
{
png_set_expand_gray_1_2_4_to_8(PngPointer);
//png_set_expand(PngPointer);
//png_set_bgr(PngPointer); //R=G=B so there's no need to swap RGB values
png_set_gray_to_rgb(PngPointer);
break;
}

case PNG_COLOR_TYPE_PALETTE:
{
png_set_palette_to_rgb(PngPointer);
if (png_get_valid(PngPointer, InfoPointer, PNG_INFO_tRNS))
{
png_set_tRNS_to_alpha(PngPointer);
BGneeded = true;
}
else
png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);
png_set_bgr(PngPointer);
BitsPerPixel = 32;
break;
}

case PNG_COLOR_TYPE_GRAY_ALPHA:
{
png_set_gray_to_rgb(PngPointer);
break;
}

case PNG_COLOR_TYPE_RGB:
{
png_set_bgr(PngPointer);
png_set_filler(PngPointer, 0xFF, PNG_FILLER_AFTER);
BitsPerPixel = 32;
break;
}

case PNG_COLOR_TYPE_RGBA:
{
png_set_bgr(PngPointer);
BitsPerPixel = 32;
break;
}

default: png_destroy_read_struct(&PngPointer, &InfoPointer, nullptr); throw std::runtime_error("Error: Png Type not supported."); break;
}

//SET BACKGROUND
png_color_16 my_background;
png_color_16p image_background;

my_background.red = 255;
my_background.green = 255;
my_background.blue = 255;

if (png_get_bKGD(PngPointer, InfoPointer, &image_background))
png_set_background(PngPointer, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
else if (BGneeded)
png_set_background(PngPointer, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
//END SET BACKGROUND

png_read_update_info(PngPointer, InfoPointer);
channels = png_get_channels(PngPointer, InfoPointer);
png_get_IHDR(PngPointer, InfoPointer, &width, &height, &bitdepth, &colortype, &interlacetype, nullptr, nullptr);

关于c++ - LibPng 背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14024240/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com