首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LibPng背景

LibPng背景
EN

Stack Overflow用户
提问于 2012-12-24 17:42:50
回答 1查看 2.9K关注 0票数 1

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

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

代码语言:javascript
复制
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);

我的保存设置是:

代码语言:javascript
复制
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);

巴布亚新几内亚的情况如下:

当我通过C++将其保存为位图时,它看起来像是(8位一位这样做):

把它保存回PNG,它看起来和原来的一模一样。8岁和16岁的人都能省回罚款。

问题是,如果我取消注释"SetBackground“节,它可以完美地保存为位图,但当我将其保存回PNG时,由于代码将其设置为白色(255、255、255),背景不再透明。

我怎么才能解决这个问题?

EN

回答 1

Stack Overflow用户

发布于 2012-12-27 07:41:50

我对你的代码做了一些修改。未测试!

代码语言:javascript
复制
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);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14024240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档