write_png.c
来自「VLC媒体播放程序」· C语言 代码 · 共 239 行
C
239 行
/***************************************************************************** * Dump an Image to a Portable Network Graphics (PNG) file **************************************************************************** Copyright (C) 2004 VideoLAN Author: Rocky Bernstein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/#include "config.h"#ifdef HAVE_LIBPNG#include <stdio.h>#include <stdlib.h>#include "write_png.h"#include <setjmp.h>typedef void (*snapshot_messenger_t)(char *message);#define _(x) x/* * Error functions for use as callbacks by the png libraries */void error_msg(char *message) { printf("error: %s\n", message);}void warning_msg(char *message) { printf("warning: %s\n", message);}static snapshot_messenger_t error_msg_cb = error_msg;static snapshot_messenger_t warning_msg_cb = warning_msg;static void user_error_fn(png_structp png_ptr, png_const_charp error_msg){ if(error_msg_cb) { char uerror[4096]; memset(&uerror, 0, sizeof(uerror)); sprintf(uerror, _("Error: %s\n"), error_msg); error_msg_cb(uerror); }}static void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg){ if(error_msg_cb) { char uerror[4096]; memset(&uerror, 0, sizeof(uerror)); sprintf(uerror, _("Error: %s\n"), warning_msg); warning_msg_cb(uerror); }}/* Dump an image to a Portable Network Graphics (PNG) file. File_name is where the file goes, i_height and i_width are the height and width in pixels of the image. The data for the image is stored as a linear array of one byte for each of red, green, and blue components of an RGB pixel. Thus row[i] will begin at rgb_image + i*(i_width*3) and the blue pixel at image[i][0] would be rgb_image + i*(i_width*3) + 1. */void write_png(const char *file_name, png_uint_32 i_height, png_uint_32 i_width, void *rgb_image, /*in*/ png_text *text_ptr, int i_text_count ){ FILE *fp; png_structp png_ptr; png_infop info_ptr; png_color_8 sig_bit; png_bytep *row_pointers; unsigned int i,j; /* open the file */ fp = fopen(file_name, "wb"); if (fp == NULL) return; /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also check that * the library version is compatible with the one used at compile time, * in case we are using dynamically linked libraries. REQUIRED. */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, user_error_fn, user_warning_fn); if (png_ptr == NULL) { fclose(fp); return; } /* Allocate/initialize the image information data. REQUIRED */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return; } /* Set error handling. REQUIRED if you aren't supplying your own * error handling functions in the png_create_write_struct() call. */ if (setjmp(png_ptr->jmpbuf)) { /* If we get here, we had a problem writing the file */ fclose(fp); png_destroy_write_struct(&png_ptr, (png_infopp) &info_ptr); return; } /* Set up the output control using standard C streams. This is required. */ png_init_io(png_ptr, fp); /* Set the image information here. i_width and i_height are up to 2^31, * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED */ png_set_IHDR(png_ptr, info_ptr, i_width, i_height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* For color images: */ sig_bit.red = 8; sig_bit.green = 8; sig_bit.blue = 8; if (text_ptr) png_set_text(png_ptr, info_ptr, text_ptr, i_text_count); /* Write the file header information. REQUIRED */ png_write_info(png_ptr, info_ptr); /* Once we write out the header, the compression type on the text * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again * at the end. */ /* Shift the pixels up to a legal bit depth and fill in * as appropriate to correctly scale the image. */ png_set_shift(png_ptr, &sig_bit); /* pack pixels into bytes */ png_set_packing(png_ptr); row_pointers = png_malloc(png_ptr, i_height*sizeof(png_bytep *)); for (i=0, j=0; i<i_height; i++, j+=i_width*3) { row_pointers[i] = rgb_image + j; } png_set_rows (png_ptr, info_ptr, row_pointers); png_write_image(png_ptr, row_pointers); /* You can write optional chunks like tEXt, zTXt, and tIME at the end * as well. */ /* It is REQUIRED to call this to finish writing the rest of the file */ png_write_end(png_ptr, info_ptr); /* if you allocated any text comments, free them here */ /* free image data if allocated. */ /* clean up after the write, and free any memory allocated */ png_destroy_info_struct(png_ptr, &info_ptr); /* clean up after the write, and free any memory allocated */ png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fclose(fp); return;}#ifdef STANDALONEintmain(int argc, char **argv) { char image_data[3*16 * 3*16 * 3]; int i,j,k,l,m; char r,g,b,t, or,og,ob; or=0x00; og=0xFF; ob=0x0; m=0; for (i=0; i<3; i++) { t=or; or=og; og=ob; ob=t; for (j=0; j<16; j++) { r=or; g=og; b=ob; for (k=0; k<3; k++) { for (l=0; l<16; l++) { image_data[m++]=r; image_data[m++]=g; image_data[m++]=b; } t=r; r=g; g=b; b=t; } } } write_png("/tmp/pngtest.png", 3*16, 3*16, (void *) image_data) ; return 0;}#endif /*STANDALONE*/#endif /*HAVE_LIBPNG*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?