1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > c语言读取png文件大小 求助: C语言- 利用libpng读取png大小 并转换为jpg类型图片...

c语言读取png文件大小 求助: C语言- 利用libpng读取png大小 并转换为jpg类型图片...

时间:2020-01-05 22:17:40

相关推荐

c语言读取png文件大小 求助: C语言- 利用libpng读取png大小 并转换为jpg类型图片...

大家好,

最近研究C语言图像处理这方面遇到一个难题,详情如下:

目标:将png类型图片的信息读入内存,提取所需要的数据并保存,然后转换为如jpg等其它图片格式。

1.libpng库已经装好,通过makefile调用库文件路径也正确。

2.写了一个读取函数,如下:

#include

#include

#include

#include

#include

#include

#include"png.h"

#include"pngio.h"

#include"error.h"

#include"image.h"

/*==============================================================================*

*read_png*

*==============================================================================*/

intx,y;

intwidth,height;

intchannels;

png_bytecolor_type;

png_bytebit_depth;

png_structppng_ptr;

png_infopinfo_ptr;

intnumber_of_passes;

png_bytep*row_pointers;

png_uint_32w,h;

size_tnpixels;

//png_uint_32*raster;

//png_uint_32

intread_png(char*input_filename,picture*thePicture,FILE*status_log)

{

interr=no_err;

charheader[8];//8isthemaximumsizethatcanbechecked

/*openfileandtestforitbeingapng*/

FILE*fp=fopen(input_filename,"rb");

if(fp){

//abort_("[read_png_file]File%scouldnotbeopenedforreading",file_name);

fread(header,1,8,fp);

/*checkedoutwithaproperPNGsignature*/

if(png_check_sig(header,8)){

/*initializestuff*/

png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);

if(png_ptr){

info_ptr=png_create_info_struct(png_ptr);

if(info_ptr){

if(setjmp(png_jmpbuf(png_ptr))){

fprintf(status_log,"Errorduringinit_io.\n");

}else{

//takesourfilestreampointer(fp)andstoresitinthepng_ptrstructforlateruse.

png_init_io(png_ptr,fp);

//letslibpngknowthatwealreadycheckedthe8signaturebytes

png_set_sig_bytes(png_ptr,8);

//informationisstoredintheinformationstruct

png_read_info(png_ptr,info_ptr);

//png_read_update_info(png_ptr,info_ptr);

width=png_get_image_width(png_ptr,info_ptr);

height=png_get_image_height(png_ptr,info_ptr);

//w=png_get_image_width(png_ptr,info_ptr);

//h=png_get_image_height(png_ptr,info_ptr);

fprintf(status_log,"png-image-details:width=%i-height=%i\n",width,height);

//npixels=width*height;

npixels=width*height;

/*Readthewholeimageintomemoryatonce.*/

/*readfile*/

if(setjmp(png_jmpbuf(png_ptr)))

fprintf(status_log,"Errorduringread_image.\n");

png_uint_32*raster=malloc(npixels*4*sizeof(png_uint_32));

//row_pointers=(png_bytep*)malloc(npixels*sizeof(png_bytep));

row_pointers=(png_bytep*)malloc(sizeof(png_bytep)*height);

for(y=0;y

row_pointers[y]=(png_byte*)malloc(png_get_rowbytes(png_ptr,info_ptr));

png_read_image(png_ptr,row_pointers);

if(raster!=NULL){

channels=png_get_channels(png_ptr,info_ptr);

fprintf(status_log,"Bild-Kanalist%d.\n",channels);

fprintf(status_log,"Bildistgeladen\n");

thePicture->pixelmap=row_pointers;

thePicture->width=width;

thePicture->height=height;

thePicture->type=png_type;

}else{

fprintf(status_log,"Memoryerror.\n");

err=mem_err;

}

fclose(fp);

}

}else{

fprintf(status_log,"png_create_info_structfailed.\n");

//err=mem_err;

}

}else{

fprintf(status_log,"png_create_read_structfailed.\n");

}

}else{

fprintf(status_log,"checkingPNGfailed.\n");

}

}else{

fprintf(status_log,"Error.Failtoopenthepng.\n");

err=file_err;

}

returnerr;

}

3.测试结果如下:

原png图片:

转换后jpg:

请问是什么原因造成这样的效果,代码有什么地方需要修改吗?

先谢谢了。

15 个解决方案

#1

是rgb赋值的时候可能出的错

一定是像素赋值算法有问题

我感觉问题应该是从这后面出现的仔细看看赋值我搞过libjpg没搞过libpng

for(y=0;ypixelmap=row_pointers;thePicture->width=width;thePicture->height=height;thePicture->type=png_type;}else{fprintf(status_log,"Memoryerror.\n");err=mem_err;}

#2

行宽计算错误。

#3

谢谢二位的回复,为我指出了一个思维方向。

@Arther_L:我也怀疑是像素赋值的问题,程序中检查了通道数是4,在另外一个C程序中有包含RGBA的结构,如下:

typedefstructpixel3{

pixelvaluer;

pixelvalueg;

pixelvalueb;

pixelvaluea;

}pixel3

逐行位置通过一个函数来计算:

get_pixel(x,y,image)(((pixel3)(image->pixelmap))[(size_t)y*(size_t)image->width+(size_t)x])

请详细说明下,非常感谢。

@zhao4zhong1:可以提示一下吗,正确的行宽计算原理是怎样的,应该怎么修改我的代码?非常感谢。

#4

原PNG文件前面的非图像数据被误以为图像数据。

#5

貌似数据读入是一行行没见你整合成一个连续块,处理[(size_t)y*(size_t)image->width+(size_t)x]下标越界,混入垃圾数据了。不处理直接按行压缩试试...

#6

感谢二位的回复,

现在我理解的是,要再对读入数据进行过滤,对吗?

@赵先生:是不是我提取png数据图像的函数用的不正确?应该用头文件函数,是吗?libpng库函数我没有完全理解,能不能请你费心帮我改下那个错误部分的代码。。真的很感谢。

@天使_su:我理解你的意思是,我malloc的问题?能不能请你详细解释一下,很感谢。

祝你们顺利。

#7

按getpixel下标取值方式,pixelmap应该是个连续块,那就一次性malloc,row_pointers各元素值定位到数据块里的某个位置,类似:

stride=png_get_rowbytes(png_ptr,info_ptr);

data=(unsigendchar*)malloc(stride*height);

for(i=0;i

row_pointers[i]=data+(height-i-1)*stride;

png_read_image(png_ptr,row_pointers);

...

thePicture->pixelmap=data;

#8

谢谢你的回复,angel_su

我程序结构如下:

1.我在另外一个头文件中(如:image.h)定义了个图片格式的结构和图片基本大小,如下:

typedefstructpixel{

pixelvaluer;

pixelvalueg;

pixelvalueb;

}pixel

typedefstructpixel3{

pixelvaluer;

pixelvalueg;

pixelvalueb;

pixelvaluea;

}pixel3

typedefstructimage{

pixel*pixelmap;

intwidth;

intheight;

}image

typedefstructpicture{

pixel*pixelmap;

intwidth;

intheight;

inttype;

}picture

//逐行读取位置函数

get_pixel(x,y,image)(((pixel)(image->pixelmap))[(size_t)y*(size_t)image->width+(size_t)x]);

get_pixel3(x,y,image)(((pixel3)(image->pixelmap))[(size_t)y*(size_t)image->width+(size_t)x]);

2.在另外的处理文件中,有个函数用来复制一个相同的图像,然后修改

3.问一个很初级的问题,因为我对png库还没有完全理解。。。

(1).这两句,我理解是为输入图片(也是输出图片)的整个大小开辟内存,对吗?

stride=png_get_rowbytes(png_ptr,info_ptr);

data=(unsigendchar*)malloc(stride*height);

(2).下面是对行指针定义,为什么计算:data+(height-i-1)*stride;?

for(i=0;i

row_pointers[i]=data+(height-i-1)*stride;

png_read_image(png_ptr,row_pointers);

(3).data和row_pointers的关系是啥?

真是麻烦你了。。谢谢。

#9

引用8楼hanow_de2的回复:

谢谢你的回复,angel_su

(2).下面是对行指针定义,为什么计算:data+(height-i-1)*stride;?

我是想直接header+data存成bmp所以把扫描线倒置,你可以改成data+i*stride...

#10

引用4楼zhao4zhong1的回复:

原PNG文件前面的非图像数据被误以为图像数据。

此结论得自于你结果图象第一行开头多了一段垃圾像素。

#11

谢谢你们回复,

但我还是。。有点一头雾水。。。

@zhao4zhong1:我想您可能是说,结果图像中黑色背景部分,就是没有填充颜色的部分。。那我应该如何修改,怎么去掉垃圾像素呢,能否具体给我个代码可以吗?谢谢。

@angel_su:不好意思,我想,可能理解你的提示了,应该用data将每一行连接起来。谢谢。

#12

比如原PNG图片前面有调色板或色彩表之类的信息被你误以为图象数据。

建议换几个尺寸相同的纯一色PNG图片试试。

#13

谢谢您的回复,赵先生

所有的图片转换后都出现这样的结果,我现在只能确定是像素赋值问题。。。但是,做了很多修改的努力,还是没成功。。。如果您能帮我看看代码,或者详细的讲一下思路,我将十分感激。

祝顺利。

#14

单纯像素操作貌似很简单,你还是上代码说明问题...

#15

libpng有自带例子代码吗?如果有,先编译链接调试其自带例子代码。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。