【问题标题】:how to let png have the transparent property如何让png具有透明属性
【发布时间】:2012-12-04 08:52:30
【问题描述】:

我已经使用 libpng 来生成 png 文件。对于RGB png,没有问题。但我想给 png 一个透明的属性。

我引用了一些代码,并将使用 * 的地方添加到标记

*行++ = 230; *PNG_COLOR_TYPE_RGBA,*

使其具有透明属性, 代码运行成功,但是没有看到透明效果。

有熟悉 libpng 或 png 操作的人可以帮帮我吗?

在这段代码中, 其中 pixel_t,& bitmap_t 是一些带有 rgb 数据的数据。

/* A colored pixel. */
typedef struct {
    uint8_t red;
    uint8_t green;
    uint8_t blue;
} pixel_t;


/* A picture. */
typedef struct  {
    pixel_t *pixels;
    size_t width;
    size_t height;
} bitmap_t;


static int save_png_to_file (bitmap_t *bitmap, const char *path)
{
    FILE * fp;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    size_t x, y;
    png_byte ** row_pointers = NULL;
    /* "status" contains the return value of this function. At first
       it is set to a value which means 'failure'. When the routine
       has finished its work, it is set to a value which means
       'success'. */
    int status = -1;
    /* The following number is set by trial and error only. I cannot
       see where it it is documented in the libpng manual.
    */
    int pixel_size = 3;
    int depth = 8;

    fp = fopen (path, "wb");
    if (! fp) {
        goto fopen_failed;
    }

    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL) {
        goto png_create_write_struct_failed;
    }

    info_ptr = png_create_info_struct (png_ptr);
    if (info_ptr == NULL) {
        goto png_create_info_struct_failed;
    }


   // png_set_invert_alpha(png_ptr);



    /* Set up error handling. */

    if (setjmp (png_jmpbuf (png_ptr))) {
        goto png_failure;
    }

    /* Set image attributes. */


    png_set_IHDR (png_ptr,
                  info_ptr,
                  bitmap->width,
                  bitmap->height,
                  depth,
                  *PNG_COLOR_TYPE_RGBA,*
                  PNG_INTERLACE_NONE,
                  PNG_COMPRESSION_TYPE_DEFAULT,
                  PNG_FILTER_TYPE_DEFAULT);

    /* Initialize rows of PNG. */
    //(png_byte **) added by li
    row_pointers = (png_byte **)png_malloc (png_ptr, bitmap->height * sizeof (png_byte *));

    for (y = 0; y < bitmap->height; ++y) {
        //png_byte * added by li
//         png_byte *row = (png_byte *)
//             png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * pixel_size);
        png_byte *row = (png_byte *)
            png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * 4);


        row_pointers[y] = row;
        for (x = 0; x < bitmap->width; ++x) {
            pixel_t * pixel = pixel_at (bitmap, x, y);
            *row++ = pixel->red;
            *row++ = pixel->green;
            *row++ = pixel->blue;
            **row++ = 230;*

        }
    }

    /* Write the image data to "fp". */

    png_init_io (png_ptr, fp);
    png_set_rows (png_ptr, info_ptr, row_pointers);
    png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

    /* The routine has successfully written the file, so we set
       "status" to a value which indicates success. */

    status = 0;

    for (y = 0; y < bitmap->height; y++) {
        png_free (png_ptr, row_pointers[y]);
    }
    png_free (png_ptr, row_pointers);

 png_failure:
 png_create_info_struct_failed:
    png_destroy_write_struct (&png_ptr, &info_ptr);
 png_create_write_struct_failed:
    fclose (fp);
 fopen_failed:
    return status;
}

【问题讨论】:

    标签: c++ png transparent libpng


    【解决方案1】:

    具有 alpha 且 bitdepth=8 的真彩色 PNG 图像以 RGBA 顺序将透明度存储为额外通道,范围为 0-255(0=完全透明;255=完全不透明)。

    在我看来,您正在做的事情是正确的。只有值 230 表示“几乎不透明”,可能难以从视觉上检测到透明度。尝试使用其他值。

    顺便说一句,请记住还有其他方法可以为 PNG 图像添加透明度,请参阅我的回答 here

    【讨论】:

    • 你有任何即时通讯工具吗?我有一些问题要问,但需要展示照片
    • 对不起。您可以选择不让其他人看到您的电子邮件帐户。看不到。是从你的pngj项目所有者账号hgonzalez@gmail.com挖出来的吗,谢谢
    【解决方案2】:

    由于这个问题似乎是“libpng 添加透明度”的最佳答案,所以我在这个答案中添加了一个可编译的源代码

    // gcc -g -Wall -o png2 png2.c -lpng
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <png.h>
    
    #define uint8_t unsigned char
    
    typedef struct {
        uint8_t red;
        uint8_t green;
        uint8_t blue;
    } pixel_t;
    
    typedef struct  {
        pixel_t *pixels;
        size_t width;
        size_t height;
    } bitmap_t;
    
    pixel_t *pixel_at(bitmap_t *bitmap, int x, int y)
    {return &bitmap->pixels[(bitmap->width * y) + x];}
    
    static int save_png_to_file (bitmap_t *bitmap, const char *path)
    {
    FILE * fp;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    size_t x, y;
    png_byte ** row_pointers = NULL;
    pixel_t *pixel;
    
    int status = -1;
    int depth = 8;
    
    if((fp = fopen(path, "wb")) == NULL)
      goto fopen_failed;
    
    if((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL)
      goto png_create_write_struct_failed;
    
    if((info_ptr = png_create_info_struct (png_ptr)) == NULL)
            goto png_create_info_struct_failed;
    
    if(setjmp (png_jmpbuf (png_ptr)))
      goto png_failure;
    
    png_set_IHDR (png_ptr,
                  info_ptr,
                  bitmap->width,
                  bitmap->height,
                  depth,
                  PNG_COLOR_TYPE_RGBA,
                  PNG_INTERLACE_NONE,
                  PNG_COMPRESSION_TYPE_DEFAULT,
                  PNG_FILTER_TYPE_DEFAULT);
    
    row_pointers = (png_byte **)png_malloc (png_ptr, bitmap->height * sizeof (png_byte *));
    
    for(y = 0; y < bitmap->height; y++)
      {
      png_byte *row = (png_byte *)
      png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * 4);
    
      row_pointers[y] = row;
      for (x = 0; x < bitmap->width; ++x)
        {
        pixel = pixel_at (bitmap, x, y);
        *row++ = pixel->red;
        *row++ = pixel->green;
        *row++ = pixel->blue;
        *row++ = x;                   // 0 - completely transparent  255 - completely opaque
        }
      }
    
    png_init_io (png_ptr, fp);
    png_set_rows (png_ptr, info_ptr, row_pointers);
    png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
    
    status = 0;
    for(y = 0; y < bitmap->height; y++)
      png_free (png_ptr, row_pointers[y]);
    png_free (png_ptr, row_pointers);
    
    png_failure:
    png_create_info_struct_failed:
      png_destroy_write_struct (&png_ptr, &info_ptr);
    png_create_write_struct_failed:
      fclose (fp);
    fopen_failed:
      return status;
    }
    
    int main(void)
    {
    bitmap_t pic;
    unsigned char pixels[255*255*3];
    int t;
    
    pic.width = 255;
    pic.height = 255;
    
    for(t=0; t<255 * 255 * 3; t=t+3)    // Just a red square
      {
      pixels[t+0] = 255;
      pixels[t+1] = 0;
      pixels[t+2] = 0;
      }
    
    pic.pixels = (pixel_t *) &pixels;
    
    save_png_to_file(&pic, "test.png");
    
    return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-05
      • 2011-03-17
      • 2014-09-30
      • 2011-10-20
      • 2012-08-11
      • 2018-07-15
      • 2019-08-13
      • 2010-11-03
      • 1970-01-01
      相关资源
      最近更新 更多