我正在尝试从位图文件中分离出标头和像素数据。使用以下代码
($bmpHdr1, @bmpData1[0..$bmpSize-1]) = unpack "(H$hdrNibbleLen)(H2)*", $data1;
在小文件上像魅力一样工作,但在较大的文件上使用时会导致荒谬的延长处理时间。例如,一个16MB的位图图像,实际上我从未等待足够长的时间来完成它。
($bmpHdr1, @bmpData1) = unpack "(H$hdrNibbleLen)(H*)", $data1;
运行良好,但我在列表的第一个元素中获取所有像素数据,需要额外的正则表达式操作来获取所需格式的数据。有没有办法只用unpack
?
预期输出:以字节级粒度堆积像素数据,并将每个字节存储在不同的列表元素中。
真正的期望:
我想比较两个位图,找到不匹配像素的X,Y和相应的数据。由于填充和不同的每像素位数(有些是24bpp),如果不在字节级别分离,则发现不匹配的像素变成了噩梦。至少我正在这样做。
my $errPixY = floor($errByte/$rowSize);
my $errPixX = ($errByte - ($errPixY * $rowSize))/($header1{DibHdrBpp}/8);
答案 0 :(得分:3)
XOR:
0 0 -> 0
0 1 -> 1
1 0 -> 1
1 1 -> 0
将有效负载保留为字符串形式,并对两个字符串进行异或运算:
my $xor = $bmp_data1 ^ $bmp_data2;
while ($xor =~ /[^\0]/g) {
my $pos = $-[0];
printf "Difference at byte %d (%02X vs %02X)\n",
$pos,
ord(substr($bmp_data1, $pos, 1)),
ord(substr($bmp_data2, $pos, 1));
}
开始找出一个字节属于哪个像素。
sub to_num { unpack('N', substr(("\0"x4).$_[0], -4)) }
my $Bpp = $bpp<8 ? 1 : $bpp/8;
die "Unsupported number of bits per pixel\n" if $Bpp != int($Bpp);
die "Unsupported number of bits per pixel\n" if $Bpp > 4;
my $xor = $data1 ^ $data2;
while ($xor =~ /[^\0]/g) {
my $pos = $-[0] - ($-[0] % $Bpp);
pos($xor) = $pos + $Bpp;
if ($bpp >= 8) {
my $pixel = $pos / $Bpp
my $x = $pixel % $row_size;
my $y = ($pixel - $x) / $row_size;
my $val1 = to_num(substr($data1, $pos, $Bpp));
my $val2 = to_num(substr($data2, $pos, $Bpp));
...
} else {
my $sub_data1 = substr($data1, $pos, 1);
my $sub_data2 = substr($data2, $pos, 1);
... split into pixels and compare those ...
}
}