Ali*_*avi 3 png image-processing deflate libpng
我想读取png文件,请参阅图像数据并再次写入,文件大小没有任何变化.基于libpng文档,png是无损的,使用deflate和lz77进行压缩.在libpng中有一个示例项目声称可以无损地读写图像,它在像素值方面是正确的,但是改变文件的结构(例如IDAT的数量,可选的块等)png文件大小.
我的明确问题:如何从压缩流(libpng中的Zstream)中提取编码参数(例如deflate params或lz77 params)并使用此参数对原始图像进行编码以创建与输入文件相同的图像文件而不进行任何更改?
这是我的代码.我试着在info_ptr中保持params 来写图像,但不能正常工作.怎么做?
int main(int argc, char *argv[])
{
inname = argv[1];
outname = argv[2];
png_structrp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop info_ptr = png_create_info_struct(read_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&read_ptr, (png_infopp)NULL, (png_infopp)NULL);
}
png_FILE_p imageFile, imageFile2, imageFileW;
imageFile=fopen(inname, "rb"); imageFileW = fopen(outname, "wb"); imageFile2 = fopen(inname, "rb");
int fileSize=fsize(imageFile2);
unsigned char* bufImWrite = malloc(sizeof(char)*fileSize);
fread(bufImWrite, 1, fileSize, imageFile2);
png_init_io(read_ptr, imageFile);
png_read_info(read_ptr, info_ptr);
png_uint_32 height;
height = info_ptr->height;
png_bytep * row_pointers;
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for (int y = 0; y < height; y++)
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(read_ptr, info_ptr));
png_read_image(read_ptr, row_pointers);
png_read_end(read_ptr, info_ptr);
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);;
png_init_io(png_ptr, imageFileW);
png_write_info(png_ptr, info_ptr);
//png_set_compression_level(png_ptr, 9);
//png_set_compression_window_bits(png_ptr, 15);
//png_set_compression_strategy(png_ptr, 3);
//png_set_compression_mem_level(png_ptr, 8);
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, info_ptr);
}
Run Code Online (Sandbox Code Playgroud)
PNG文件不包含用于压缩的确切deflate/zlib参数的记录,因此您无法实现所需.如果您需要保留原始编码,则应保留原始PNG文件的副本,而不是破坏性地阅读它.
如果要在不更改图像数据的情况下更改辅助PNG块,请使用某些应用程序(如tweakpng)将原始PNG文件中的IHDR,PLTE,IDAT和IEND块复制到新文件中.
如果,如评论所示,您想要在不更改压缩数据流的情况下添加水印,那根本不可能,因为图像数据不同.如果您确实需要可移动水印,请使用某些可编辑格式(如SVG)以保持水印分离,或使用APNG等格式将水印存储在单独的部分中.这样做的缺点是任何人都可以从他们的副本中删除水印.
除了 Glenn 的正确响应之外,即使您以某种方式拥有用于压缩的参数,压缩也可能是由不再可用的代码完成的,或者是由您无法使用的专有代码完成的。无论哪种情况,都无法复制精确的压缩数据。如果您不想弄乱图像,只需保留原始压缩数据。