Programowanie w systemie UNIX/c grafika/libpng
Instalacja
edytujInstalacja 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
edytujCzytanie 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:
./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- stackoverflow - libpng [2]
- libpng at sourceforge
- github repo by glennrp (libpng)
- home page