Przejdź do zawartości

Programowanie w systemie UNIX/c grafika/libpng

Z Wikibooks, biblioteki wolnych podręczników.

Instalacja

[edytuj]

Instalacja pakietów:

sudo apt-get install libpng-dev

Kod żródłowy:


git clone git@github.com:glennrp/libpng.git

i następnie

./configure 
make check
sudo make install

Przykłady

[edytuj]

Czytanie pliku

[edytuj]
/*

based on the 
https://github.com/gbenison/png-text-embed
with small modifications

gcc png-text-dump.c -L/usr/local/lib -lpng -o png-text-dump // with png library
./png-text-dump r.png


*/
#include <stdio.h>
#include <png.h> // libpng 

int
main(int argc, char *argv[])
{
  FILE *infile = stdin;
  if (argc > 1)
    infile = fopen(argv[1], "r");

  if (infile == NULL)
    {
      fprintf(stderr, "Could not open %s\n", argv[1]);
      return 1;
    }

  fprintf(stdout, "File %s opened with libpng version  %s\n", argv[1], PNG_LIBPNG_VER_STRING);

  /* allocate png structures */
  png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
						NULL, NULL, NULL);

  png_infop read_info_ptr = png_create_info_struct(read_ptr);
  png_infop end_info_ptr = png_create_info_struct(read_ptr);

  png_init_io(read_ptr, infile);
  png_read_png(read_ptr, read_info_ptr, 0, NULL);
  
  png_textp text_ptr;
  int num_text;
  png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text);

  /* echo text contents. */
  int i;
  for (i = 0; i < num_text; ++i)
    {
      printf("==== text chunk %d: \"%s\" = tEXt%s ====\n", i + 1, text_ptr[i].key, text_ptr[i].key);
      printf("%s\n\n", text_ptr[i].text);
    }

  return 0;
}

Wczytamy plik z commons:

plik z opisem
./png-text-dump r.png

i otrzymamy:

 File r.png opened with libpng version  1.2.50
==== text chunk 1: "Title" = tEXtTitle ====
RGBA Logo

==== text chunk 2: "Author" = tEXtAuthor ====
Shlomi Tal

==== text chunk 3: "Description" = tEXtDescription ====
Image demonstrating the use of an alpha channel for anti-aliasing of transparency and for translucency

==== text chunk 4: "Comment" = tEXtComment ====
This is the large version, with a dot size of 100 micrometres (254 DPI), yielding 15 cm for both width and height

==== text chunk 5: "Comment" = tEXtComment ====
Colours are from the Gretag-Macbeth palette

==== text chunk 6: "Copyright" = tEXtCopyright ====
Creative Commons Attribution-ShareAlike 3.0 and older

==== text chunk 7: "Software" = tEXtSoftware ====
GIMP 2.2.10

==== text chunk 8: "Creation Time" = tEXtCreation Time ====
Tue 18 Mar 2008 16:03 +0200


Tworzenie pliku

[edytuj]
  • program wg Andrew Greensted[1]

PNG16 gray

[edytuj]
 
/*
I'm trying to write (using libpng) an 16-bit grayscale image where each point color equals to sum of its coordinates. The following code should produce a 16-bit PNG, but instead produces 8-bit like this. Why?
https://stackoverflow.com/questions/8818206/16-bit-grayscale-png



gcc p.c -L/usr/local/lib -lpng  -Wall -Wextra

*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <png.h>// libpng 




void save_png(FILE* fp, long int size)
{
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    int x, y;
    png_bytepp row_pointers;
    int iMax = (int) size;
    int yMax = (int) size;

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

    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        png_destroy_write_struct(&png_ptr, NULL);
        return ;
    }

     if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return ;
    }

    png_set_IHDR(png_ptr, info_ptr,
                 size, size, // width and height
                 16, // bit depth
                 PNG_COLOR_TYPE_GRAY, // color type
                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

    /* Initialize rows of PNG. */
    row_pointers = (png_bytepp)png_malloc(png_ptr, size* sizeof(png_bytep));

    for (int i=0; i< iMax; i++)
       row_pointers[i]=NULL;

    for (int i=0; i< iMax; i++)
       row_pointers[i]=png_malloc(png_ptr, size*2);

    //set row data
    for (y = 0; y < yMax; ++y) {
        png_bytep row = row_pointers[y];
        for (x = 0; x < iMax; ++x) {
                short color = x+y;
                *row++ = (png_byte)(color & 0xFF);
                *row++ = (png_byte)(color >> 8);
        }
    }

    /* Actually write the image data. */
    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);
    //png_write_image(png_ptr, row_pointers);

    /* Cleanup. */
    for (y = 0; y < yMax; y++) {
        png_free(png_ptr, row_pointers[y]);
    }
    png_free(png_ptr, row_pointers);
    png_destroy_write_struct(&png_ptr, &info_ptr);
}

int main()
{
  FILE* f;
  if((f=fopen("PNG16g.png", "wb"))!=NULL)
  {
    save_png(f, 1000);

    fclose(f);
  }
  return 0;
}

Sprawdzamy plik

pngcheck -cvt ./PNG16g.png

Wynik

File: ./PNG16g.png (12449 bytes)
  chunk IHDR at offset 0x0000c, length 13
    1000 x 1000 image, 16-bit grayscale, non-interlaced
  chunk IDAT at offset 0x00025, length 8192
    zlib: deflated, 32K window, default compression
  chunk IDAT at offset 0x02031, length 4188
  chunk IEND at offset 0x03099, length 0
No errors detected in ./PNG16g.png (4 chunks, 99.4% compression).

Programy wykorzystujące libpng

[edytuj]
  • Image Magic

pomoc

[edytuj]

źródła

[edytuj]
  1. program tworzenia pliku png - Andrew Greensted
  2. stackoverflow. questions tagged : libpng