Saturday, July 16, 2016

how to access EACH PIXEL-of-PNG-DATA-BYTES with C language?




Question?

  How to combine aaa-pixel of PNG into rgb-pixel of another PNG with the same size?
  

Cited From github

Third Party Library Png.h Required

Reference to POST(clik.me)  if there is problem when generate png library.


SOURCE CODE

/*
* A simple libpng example program
* http://zarb.org/~gc/html/libpng.html
*
* Modified by Yoshimasa Niwa to make it much simpler
* and support all defined color_type.
*
* To build, use the next instruction on OS X.
* $ brew install libpng
* $ clang -lz -lpng15 libpng_test.c
*
* Copyright 2002-2010 Guillaume Cottenceau.
*
* This software may be freely redistributed under the terms
* of the X11 license.
*
*/

#include <stdlib.h>
#include <stdio.h>
#include <png.h>

int width;
int height;
png_byte    color_type;
png_byte    bit_depth;
png_bytep * row_pointers;

void read_png_file(char * filename)
{
    FILE * fp = fopen(filename, "rb");
    if (nullptr == fp)abort();

    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png)abort();

    png_infop info = png_create_info_struct(png);
    if (!info)abort();

    if (setjmp(png_jmpbuf(png)))abort();

    png_init_io(png, fp);
    png_read_info(png, info);

    width       = png_get_image_width(png, info);
    height      = png_get_image_height(png, info);
    color_type  = png_get_color_type(png, info);
    bit_depth   = png_get_bit_depth(png, info);

    // read any color_type into 8bit depth, RGBA format.

    if (16 == bit_depth)
        png_set_strip_16(png);

    if (PNG_COLOR_TYPE_PALETTE == color_type)
        png_set_palette_to_rgb(png);

    // PNG_CLOR_TYPE_GRAY_ALPHA is always 8-or-16bit depth
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_expand_gray_1_2_4_to_8(png);

    // These color_type don't have an alpha channel then fill it with 0xff.
    if (PNG_COLOR_TYPE_RGB ||
        PNG_COLOR_TYPE_GRAY ||
        PNG_COLOR_TYPE_PALETTE)
        png_set_filler(png, 0xFF, PNG_FILLER_AFTER);

    if (PNG_COLOR_TYPE_GRAY == color_type || PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png);

    png_read_update_info(png, info);

    row_pointers = (png_bytep *)malloc(sizeof(png_bytep) * height);
    for (int y = 0; y < height; ++y)
        row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));

    png_read_image(png, row_pointers);

    fclose(fp);
}

void write_png_file(char *filename) {
    int y;

    FILE *fp = fopen(filename, "wb");
    if (!fp) abort();

    png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png) abort();

    png_infop info = png_create_info_struct(png);
    if (!info) abort();

    if (setjmp(png_jmpbuf(png))) abort();

    png_init_io(png, fp);

    // Output is 8bit depth, RGBA format.
    png_set_IHDR(
        png,
        info,
        width, height,
        8,
        PNG_COLOR_TYPE_RGBA,
        PNG_INTERLACE_NONE,
        PNG_COMPRESSION_TYPE_DEFAULT,
        PNG_FILTER_TYPE_DEFAULT
        );
    png_write_info(png, info);

    // To remove the alpha channel for PNG_COLOR_TYPE_RGB format,
    // Use png_set_filler().
    //png_set_filler(png, 0, PNG_FILLER_AFTER);

    png_write_image(png, row_pointers);
    png_write_end(png, NULL);

    for (int y = 0; y < height; y++) {
        free(row_pointers[y]);
    }
    free(row_pointers);

    fclose(fp);
}

void process_png_file() {
    for (int y = 0; y < height; y++) {
        png_bytep row = row_pointers[y];
        for (int x = 0; x < width; x++) {
            png_bytep px = &(row[x * 4]);
            // Do something awesome for each pixel here...
            //printf("%4d, %4d = RGBA(%3d, %3d, %3d, %3d)\n", x, y, px[0], px[1], px[2], px[3]);
        }
    }
}


Done.:-)
End
__________________________________________________________________

No comments:

Post a Comment