1.環(huán)境準(zhǔn)備
安裝libjpeg庫(kù)和libpng庫(kù)
2.定義結(jié)構(gòu)體
//使用該結(jié)構(gòu)體存儲(chǔ)圖片數(shù)據(jù)
typedef struct img_pic_data pic_data;
struct img_pic_data
{
int width, height;
int bit_depth;
int quality;
int flag;
int col_type;
unsigned char *rgba;
};
3.加載jpeg圖片到結(jié)構(gòu)體
int LoadJPG(char *file, pic_data *data)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jem;
FILE *jpeg_fp;
JSAMPARRAY buffer;
int row_stride;
int pos;
int i;
//打開(kāi)jpeg格式圖片
if((jpeg_fp = fopen(file, "rb")) == NULL)
{
printf("can't open %s\n", file);
return -1;
}
//初始化并申請(qǐng)解碼器
cinfo.err = jpeg_std_error(&jem);
jpeg_create_decompress(&cinfo);
//指定圖片文件信息
jpeg_stdio_src(&cinfo, jpeg_fp);
//讀取頭部信息
jpeg_read_header(&cinfo, TRUE);
//開(kāi)始解碼
jpeg_start_decompress(&cinfo);
row_stride = cinfo.output_width * cinfo.output_components;
data->width = cinfo.output_width;
data->height = cinfo.output_height;
data->bit_depth = 8;
data->flag = 1;
data->col_type = PNG_COLOR_TYPE_RGB_ALPHA;
pos = 0;
//給一行數(shù)據(jù)分配內(nèi)存
buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
//一行一行讀取
while(cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, buffer, 1);
for(i=0; i<cinfo.output_width; i++)
{
data->rgba[4*pos+0] = buffer[0][3*i+0];
data->rgba[4*pos+1] = buffer[0][3*i+1];
data->rgba[4*pos+2] = buffer[0][3*i+2];
data->rgba[4*pos+3] = 255;
pos++;
}
}
//讀取結(jié)束
jpeg_finish_decompress(&cinfo);
//釋放編碼器對(duì)象
jpeg_destroy_decompress(&cinfo);
//關(guān)閉jpeg格式圖片
fclose(jpeg_fp);
return 0;
}
4.將圖像數(shù)據(jù)寫(xiě)入png文件
int PutPNG(char *file, pic_data *data)
{
FILE *pic_fp;
png_structp png_ptr;
png_infop info_ptr;
png_bytep *row_pointers;
int color_type, channels;
int temp;
int i, j;
int size, pos = 0;
//打開(kāi)png空文件
pic_fp = fopen(file, "wb");
if(pic_fp == NULL)
{
printf("can't open %s\n", file);
return -1;
}
temp = data->width * 4;
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr)
{
printf("png_create_write_struct failed\n");
return -1;
}
info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr)
{
printf("png_create_info_struct failed\n");
return -1;
}
if(setjmp(png_jmpbuf(png_ptr)))
{
printf("write error on init io\n");
return -1;
}
png_init_io(png_ptr, pic_fp);
if(setjmp(png_jmpbuf(png_ptr)))
{
printf("write error on write header\n");
return -1;
}
png_set_IHDR(png_ptr, info_ptr, data->width, data->height, data->bit_depth, data->col_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
if(setjmp(png_jmpbuf(png_ptr)))
{
printf("write error on writing bytes\n");
return -1;
}
if(data->flag == 1)
{
pos = 0;
row_pointers = (png_bytep *)malloc(data->height * sizeof(png_bytep));
for(i=0; i<data->height; i++)
{
row_pointers[i] = (png_bytep)malloc(temp * sizeof(unsigned char));
for(j=0; j<temp; j+=4)
{
row_pointers[i][j+0] = data->rgba[pos*4 + 0];
row_pointers[i][j+1] = data->rgba[pos*4 + 1];
row_pointers[i][j+2] = data->rgba[pos*4 + 2];
row_pointers[i][j+3] = data->rgba[pos*4 + 3];
pos++;
}
}
png_write_image(png_ptr, row_pointers);
if(setjmp(png_jmpbuf(png_ptr)))
{
printf("write error on write end\n");
return -1;
}
png_write_end(png_ptr, NULL);
for(i=0; i<data->height; i++)
{
free(row_pointers[i]);
}
free(row_pointers);
}
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(pic_fp);
return 0;
}
5.通過(guò)main函數(shù)輸入jpeg文件和png文件名
int main(int argc, char **argv)
{
FILE *file;
pic_data pic_data;
char rgba_data[16*300*300];
char jpeg_name[256];
char png_name[256];
int ret;
memset(jpeg_name, 0x00, sizeof(jpeg_name));
memset(png_name, 0x00, sizeof(png_name));
if(argc != 3)
{
printf("入?yún)€(gè)數(shù)錯(cuò)誤!\n");
return -1;
}
strncpy(jpeg_name, argv[1], 255);
strncpy(png_name, argv[2], 255);
pic_data.rgba = rgba_data;
ret = LoadJPG(jpeg_name, &pic_data);
if(ret < 0)
{
printf(" LoadJPG error!\n");
return -1;
}
ret = PutPNG(png_name, &pic_data);
if(ret < 0)
{
printf(" PutPNG error!\n");
return -1;
}
return 0;
}
6.加上頭文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jpeglib.h>
#include <png.h>
7.編譯
$ gcc -o examle example.c -L$HOME/local/prior/lib -ljpeg -lpng
8.運(yùn)行
$ ./examle a.jpg b.png