网上一段计算图片 pHash(perceptual hash)的 php 代码,我把它更改了一下:
function phash(file)
{
$resource=imagecreatefromstring(file_get_contents($file));
$size=8;
$width = $size + 1;
$heigth = $size;
$resized = imagecreatetruecolor($width, $heigth);
imagecopyresampled($resized, $resource, 0, 0, 0, 0, $width, $heigth, imagesx($resource), imagesy($resource));
$hash = 0;
$one = 1;
for ($y = 0; $y < $heigth; $y++) {
$rgb = imagecolorsforindex($resized, imagecolorat($resized, 0, $y));
$left = floor(($rgb['red'] + $rgb['green'] + $rgb['blue']) / 3);
for ($x = 1; $x < $width; $x++) {
$rgb = imagecolorsforindex($resized, imagecolorat($resized, $x, $y));
$right = floor(($rgb['red'] + $rgb['green'] + $rgb['blue']) / 3);
if ($left > $right) {
$hash |= $one;
}
$left = $right;
$one = $one << 1;
}
}
imagedestroy($resized);
return dechex($hash);
}
不知道 pHash 的同学可以先 Google 一下概念,上面的代码是我微改后的代码,原理貌似还是很好理解,就是把一张图片压缩成 8x8 的图片并计算 64 个像素灰度平均值,然后遍历每个像素和这个平均值比较,生成一个布尔值最后返回这个值的 16 进制,但是目前在两种环境下测试:
因为源代码里面有点不懂:
2
WytheHuang 2017-06-01 09:11:12 +08:00
|
4
mcfog 2017-06-01 10:08:42 +08:00
应该不是 php 版本的问题,而是 32 位 64 位的关系,32 位的整数转换成 hex 最大就是 8 位,你这个算法用 32 位的机器跑相当于直接溢出了
要测试也很简单,在你 32 位的机器上装个 7,在 64 位机器上装个 5 交叉试一下就知道了 如果要支持 32 位机器,或者更大的 size,可以在内层循环就 dechex 一下用字符串拼接来累计结果,而不是整数 |
6
we3613040 2017-06-01 10:22:49 +08:00
循环是 8*8 =64 次,会出现两个结果是那个 if 条件的问题,不过按道理说,这种 api 不应该会出现版本差异
|
8
Reign OP @mcfog 即使不转成 16 进制,同一张图片,32 位 php5.5 得出的结果是:5779363675144030163,64 位 php7.1 得出结果为:1690404819
|