как дать png иметь свойство прозрачности

Я использовал 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;
}

0

Решение

В полноцветном PNG-изображении с альфа-каналом с bitdepth = 8 прозрачность сохраняется как дополнительный канал в порядке RGBA в диапазоне 0–255 (0 = полностью прозрачный; 255 = полностью непрозрачный).

То, что вы делаете, выглядит правильно для меня. Только то, что значение 230 означает «почти непрозрачный», может быть трудно визуально определить прозрачность. Попробуйте с другими значениями.

Кстати, имейте в виду, что есть другие способы добавить прозрачность в изображение PNG, смотрите мой ответ Вот.

1

Другие решения

Так как этот вопрос, кажется, лучший ответ для «libpng add прозрачности», я добавляю готовый источник компиляции к этому ответу

// 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;
}
0

По вопросам рекламы [email protected]