user-0 提问: 求助: C语言- 利用libpng读取png大小，并转换为jpg类型图片

回复:
user: user-1
content: 单纯像素操作貌似很简单，你还是上代码说明问题...

user: user-2
content: libpng有自带例子代码吗？如果有，先编译链接调试其自带例子代码。

user: user-0
content: 谢谢您的回复，赵先生  所有的图片转换后都出现这样的结果，我现在只能确定是像素赋值问题。。。但是，做了很多修改的努力，还是没成功。。。如果您能帮我看看代码，或者详细的讲一下思路，我将十分感激。  祝顺利。

user: user-2
content: 比如原PNG图片前面有调色板或色彩表之类的信息被你误以为图象数据。 建议换几个尺寸相同的纯一色PNG图片试试。

user: user-0
content: 谢谢你们回复，  但我还是。。有点一头雾水。。。  @zhao4zhong1: 我想您可能是说，结果图像中黑色背景部分，就是没有填充颜色的部分。。那我应该如何修改，怎么去掉垃圾像素呢, 能否具体给我个代码可以吗? 谢谢。  @angel_su: 不好意思，我想，可能理解你的提示了，应该用data将每一行连接起来。谢谢。

user: user-2
content: 引用 4 楼 zhao4zhong1 的回复:原PNG文件前面的非图像数据被误以为图像数据。 此结论得自于你结果图象第一行开头多了一段垃圾像素。

user: user-1
content: 引用 8 楼 hanow_de2 的回复:谢谢你的回复， angel_su    (2). 下面是对行指针定义，为什么计算: data + (height - i - 1) * stride; ? 我是想直接header+data存成bmp所以把扫描线倒置，你可以改成data + i * stride...

user: user-0
content: 谢谢你的回复， angel_su  我程序结构如下:  1. 我在另外一个头文件中(如: image.h)定义了个图片格式的结构和图片基本大小，如下:    typedef struct pixel{    pixelvalue r; pixelvalue g; pixelvalue b;    }pixel   typedef struct pixel3{    pixelvalue r; pixelvalue g; pixelvalue b; pixelvalue a;    }pixel3   typedef struct image{  pixel *pixelmap; int width; int height;  }image  typedef struct picture{  pixel *pixelmap; int width; int height; int type;   }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 = (unsigend char *)malloc(stride * height);  (2). 下面是对行指针定义，为什么计算: data + (height - i - 1) * stride; ?  for (i = 0; i < height; i++)     row_pointers[i] = data + (height - i - 1) * stride;  png_read_image(png_ptr, row_pointers);  (3). data 和 row_pointers的关系 是啥?  真是麻烦你了。。谢谢。

user: user-1
content: 按getpixel下标取值方式，pixelmap应该是个连续块，那就一次性malloc, row_pointers各元素值定位到数据块里的某个位置， 类似：  stride = png_get_rowbytes(png_ptr, info_ptr); data = (unsigend char *)malloc(stride * height);  for (i = 0; i < height; i++)     row_pointers[i] = data + (height - i - 1) * stride;  png_read_image(png_ptr, row_pointers);  ...  thePicture->pixelmap = data;

user: user-0
content: 感谢二位的回复，  现在我理解的是，要再对读入数据进行过滤，对吗?  @赵先生: 是不是我提取png数据图像的函数用的不正确? 应该用头文件函数，是吗? libpng库函数我没有完全理解，能不能请你费心帮我改下那个错误部分的代码。。真的很感谢。  @天使_su: 我理解你的意思是，我malloc的问题? 能不能请你详细解释一下，很感谢。  祝你们顺利。

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

user: user-2
content: 原PNG文件前面的非图像数据被误以为图像数据。

user: user-2
content: 行宽计算错误。

user: user-3
content: 是 r g b赋值的时候 可能出的错  一定是像素赋值 算法有问题 我感觉问题应该是从这后面出现的 仔细看看赋值 我搞过libjpg 没搞过libpng   for (y=0; y<height; 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-Kanal ist %d .\n", channels);                               fprintf(status_log,"Bild ist geladen\n");                               thePicture->pixelmap = row_pointers;                             thePicture->width = width;                             thePicture->height = height;                             thePicture->type = png_type;                                                         }else{                                   fprintf(status_log,"Memory error.\n");                                 err = mem_err;                           }

user: user-0
content: 谢谢二位的回复，为我指出了一个思维方向。  @Arther_L: 我也怀疑是像素赋值的问题，程序中检查了通道数是4, 在另外一个C程序中有包含RGBA的结构，如下:   typedef struct pixel3{   pixelvalue r; pixelvalue g; pixelvalue b; pixelvalue a;   }pixel3    逐行位置通过一个函数来计算:    get_pixel(x, y, image) (((pixel3)(image->pixelmap))[(size_t)y*(size_t)image->width+(size_t)x])    请详细说明下， 非常感谢。  @zhao4zhong1: 可以提示一下吗，正确的行宽计算原理是怎样的，应该怎么修改我的代码? 非常感谢。