歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

利用libpng中的函數讀寫PNG文件

利用libpng中的函數讀寫PNG文件。分享一下我使用的代碼,以下是讀取png圖片文件的代碼:

#include <stdio.h>
#include <png.h>
#include <stdlib.h>
/******************************圖片數據*********************************/
typedef struct _pic_data pic_data;
struct _pic_data
{
 int width, height; /* 尺寸 */
 int bit_depth;  /* 位深 */
 int flag;   /* 一個標志,表示是否有alpha通道 */

 unsigned char **rgba; /* 圖片數組 */
};
/**********************************************************************/
#define PNG_BYTES_TO_CHECK 4
#define HAVE_ALPHA 1
#define NO_ALPHA 0


int detect_png(char *filepath, pic_data *out)
/* 用於解碼png圖片 */
{
 FILE *pic_fp;
 pic_fp = fopen(filepath, "rb");
 if(pic_fp == NULL) /* 文件打開失敗 */
  return -1;
 
 /* 初始化各種結構 */
 png_structp png_ptr;
 png_infop  info_ptr;
 char        buf[PNG_BYTES_TO_CHECK];
 int        temp;
 
 png_ptr  = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
 info_ptr = png_create_info_struct(png_ptr);
 
 setjmp(png_jmpbuf(png_ptr)); // 這句很重要
 
 temp = fread(buf,1,PNG_BYTES_TO_CHECK,pic_fp);
 temp = png_sig_cmp((void*)buf, (png_size_t)0, PNG_BYTES_TO_CHECK);
 
 /*檢測是否為png文件*/
 if (temp!=0) return 1;
 
 rewind(pic_fp);
 /*開始讀文件*/
 png_init_io(png_ptr, pic_fp);
 // 讀文件了
 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);

 int color_type,channels;
 
 /*獲取寬度,高度,位深,顏色類型*/
 channels      = png_get_channels(png_ptr, info_ptr); /*獲取通道數*/
 out->bit_depth = png_get_bit_depth(png_ptr, info_ptr); /* 獲取位深 */
 color_type    = png_get_color_type(png_ptr, info_ptr); /*顏色類型*/
 
 int i,j;
 int size, pos = 0;
 /* row_pointers裡邊就是rgba數據 */
 png_bytep* row_pointers;
 row_pointers = png_get_rows(png_ptr, info_ptr);
 out->width = png_get_image_width(png_ptr, info_ptr);
 out->height = png_get_image_height(png_ptr, info_ptr);
 
 size = out->width * out->height; /* 計算圖片的總像素點數量 */

 if(channels == 4 || color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 {/*如果是RGB+alpha通道,或者RGB+其它字節*/
  size *= (4*sizeof(unsigned char)); /* 每個像素點占4個字節內存 */
  out->flag = HAVE_ALPHA;    /* 標記 */
  out->rgba = (unsigned char**) malloc(size);
  if(out->rgba == NULL)
  {/* 如果分配內存失敗 */
   fclose(pic_fp);
   puts("錯誤(png):無法分配足夠的內存供存儲數據!");
   return 1;
  }

  temp = (4 * out->width);/* 每行有4 * out->width個字節 */
  for(i = 0; i < out->height; i++)
  {
   for(j = 0; j < temp; j += 4)
   {/* 一個字節一個字節的賦值 */
    out->rgba[0][pos] = row_pointers[i][j]; // red
    out->rgba[1][pos] = row_pointers[i][j+1]; // green
    out->rgba[2][pos] = row_pointers[i][j+2];  // blue
    out->rgba[3][pos] = row_pointers[i][j+3]; // alpha
    ++pos;
   }
  }
 }
 else if(channels == 3 || color_type == PNG_COLOR_TYPE_RGB)
 {/* 如果是RGB通道 */
  size *= (3*sizeof(unsigned char)); /* 每個像素點占3個字節內存 */
  out->flag = NO_ALPHA;    /* 標記 */
  out->rgba = (unsigned char**) malloc(size);
  if(out->rgba == NULL)
  {/* 如果分配內存失敗 */
   fclose(pic_fp);
   puts("錯誤(png):無法分配足夠的內存供存儲數據!");
   return 1;
  }

  temp = (3 * out->width);/* 每行有3 * out->width個字節 */
  for(i = 0; i < out->height; i++)
  {
   for(j = 0; j < temp; j += 3)
   {/* 一個字節一個字節的賦值 */
    out->rgba[0][pos] = row_pointers[i][j]; // red
    out->rgba[1][pos] = row_pointers[i][j+1]; // green
    out->rgba[2][pos] = row_pointers[i][j+2];  // blue
    ++pos;
   }
  }
 }
 else return 1;
 
 /* 撤銷數據占用的內存 */
 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
 return 0;
}

libpng 的詳細介紹:請點這裡
libpng 的下載地址:請點這裡

以下是生成png圖片文件的代碼: 見 http://www.linuxidc.com/Linux/2013-08/88649p2.htm

Copyright © Linux教程網 All Rights Reserved