【发布时间】:2022-01-10 15:20:19
【问题描述】:
情况
我目前正在制作一个从用户 ID 创建图像的函数。我已经成功地生成了原始 RGBA 像素,并且还成功地过滤了它们,如下所示:
图像宽度为 22 像素,高度为 2 像素。
用户id:a308193d1eff2f15df7bedb4cb992bcf25cee012ca41751c35ce1d5500497063,如果太短无法生成像素,将被填充。
过滤后的原始像素:
01a30819ff000000009a16e60000000000f2f7e000000000004cd8d5000000000050ac770000000000048ca3000000000011edfc00000000006163520000000000f45901000000000020322c00000000001b63b600000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
我还成功地从用户 ID 生成了一个工作 SVG,但 SVG 不是我想要的。
问题
PHP zlib 库似乎没有正确压缩数据。尽管 zlib 最初是为 PNG 设计的,但它始终输出与 PNG 格式不兼容的压缩数据。每个 zlib 库函数都会生成错误的压缩,例如:
78da 635ccc21f99f010866893d03510c9fbe3f00d33e37ae82e98035e5609aa5673198167cfb074c27260781e92f918c605ac148074c4b276f03d34c0c340200 54f010d5
(我把ZLIB头、压缩数据和adler32用空格分开了)。
它应该输出什么(或至少类似于):
0899 B5C1210A83500000D0E730582D03B1780093E730C8DAE2F0105EC213587F357B13C168B259646011B653F85E1492EC07C37303C7B9827A9941337620EE0348F70B7CDA17F8BE23505425C8DB093CDCE40F 54F010D5
(对于 PNG,压缩字符串应始终以 0x08 字节开头)
只有 Adler32 校验和每次都是正确的。
我已经尝试了每一个 zlib 压缩函数,但每一个都会产生无用的数据。其中大多数可配置的函数是 deflate_init() + deflate_add() 但它们和其他函数一样没用。
例如:
$filtered_pixels = "01a30819ff000000009a16e60000000000f2f7e000000000004cd8d5000000000050ac770000000000048ca3000000000011edfc00000000006163520000000000f45901000000000020322c00000000001b63b600000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
$options = array(
"level" => 9, // Best compression
"memory" => 1, // No need to use much memory for such small image
"window" => 8, // 256-bit window size
"strategy" => ZLIB_RLE, // Especially good for PNG compression
"dictionary" => "", // No dictionary
);
$context = deflate_init(ZLIB_ENCODING_DEFLATE , $options);
$deflate = deflate_add($context, hex2bin($filtered_pixels));
// Outputs "1819 625ccc21f99f010866893d6300814fdf1f308080cf8dab0c2010b0a69c0104587a16338080e0db3f0c2090981cc400025f2219194040c148870104a493b731800013038d00000000ffff" without adler32 checksum
echo bin2hex($deflate);
我已经为这个问题苦苦挣扎了一周,但我尝试的任何函数都无法使用我尝试的每个函数的参数。我错过了一些明显的东西吗?我也知道如何从其他部分对 PNG 进行编码,并且我已经做到了。只有 IDAT 块压缩是让我失去理智的原因。
【问题讨论】:
-
这是一个非常有趣的话题,但我对此一无所知。阅读libpng.org/pub/png/spec/1.2/PNG-Compression.html 或许
Note that the zlib compression method number is not the same as the PNG compression method number.会提供有用的提示。