如何从Imagick对象获取sha1哈希?

时间:2014-09-03 10:48:20

标签: php sha1 imagick

该网站有点像画廊。但要防止重复输入。我想要匹配它们。它不会是100%防弹图像匹配,但对我来说它是绝对完美的解决方案。

唯一的问题是,我不知道正确的方法,从 Imagick $image对象获得 sha1

这就是我现在所拥有的,它确实产生了哈希。但它与我在服务器中的那些不匹配。并且在服务器中,它将优化图像的过程与最小的缩略图相同。除此之外,在每个图像处理块的末尾都有file_put_contents($root, $image);。但我不认为问题存在,我认为问题可能是,我在$image函数内的sha1()对象中遗漏了一些东西。像sha1($image->rendercurrentimage()) ..

之类的东西
<?
$img_url = 'someimgfile.jpg';

# Step 1 = Original file hash - This is all ok
$source_hash = sha1_file($img_url);

$image = new Imagick($img_url);
# file_put_contents($source_root, $image);

$image->gaussianBlurImage(0, 0.05);
$image->setCompression(Imagick::COMPRESSION_JPEG);
$image->setCompressionQuality(90);
$image->setImageFormat('jpeg');
$image->scaleImage(215, 0);
# file_put_contents($thumbnail_root, $image);

# Step 2 = Get the thumbnail hash - results in a non matching hash vs. DB hash
$thumbnail_hash = sha1($image);

$image->setCompressionQuality(75); 
$image->cropThumbnailImage(102, 102);
# file_put_contents($smallthumbnail_root, $image);

# Step 3 = Get the even smaller thumbnail hash - results in a non matching hash vs. DB hash
$smallthumbnail_hash = sha1($image);

# now query to DB to check against all 3 hashes: $source_hash | $thumbnail_hash | $smallthumbnail_hash
# DB has lets say 1000 images, with source hash, thumbnail hash and small thumbnail hash saved in them

# NOTE: The process of scaling images as they enter the DB, is exactly the same, expect there are file_put_contents($root, $image); in between them.. I put them in and commented out, to show you the locations

正如我上面所说的那样。我有3种方式在服务器中的匹配哈希。原创,缩略图甚至更小的缩略图。这些是使用sha1_file()函数创建的。我想基本上模仿漏洞过程,但不要将文件保存在$ root中,以防它重复,并且将被拒绝并重定向到匹配的条目。

如果您想知道,为什么我要匹配缩略图。因为,我的测试表明,如果原始文件的大小可能不同等等,那么缩略图的创建,匹配很好。还是我错了?如果我有相同的图像,有3种不同的尺寸。然后我缩小它们以说出 100px 宽度。他们的哈希会是一样的吗?

结论 我不得不重写原始图像处理程序。但基本上我认为我的代码中仍然缺少$image->stripImage();。或者其他的东西。虽然它开始取得更好的结果。似乎在服务器中保持哈希的最佳方法是:

$hash = sha1(base64_encode($image->getImageBlob()));

我的测试也证实,file_put_contents($thumbnail_root, $image);然后通过sha1_file($image_root);获取哈希值不会改变哈希值。

我还从缩小到拇指大小的较大图像中获得了更多匹配结果。

2 个答案:

答案 0 :(得分:1)

由于您的问题是您不想在文件系统上为您正在经历的每个步骤创建文件,因此我建议您抓取步骤的blob内容并创建一个哈希。例如:

<?php
//quick and dirty image creation to demonstrate my point
$image = new Imagick();
$image->newImage(100, 100, new ImagickPixel('red'));
$image->setImageFormat('png');

//base64 encode our blob and then generate a sha1 hash
$thumbnail = base64_encode( $image->getImageBlob() );
echo sha1($thumbnail);

如果您尝试将两个不同(原始)尺寸的图像相互匹配,则可能会遇到重新采样问题。例如我有一张200px正方形的猴子照片,另一只看似相同的400px正方形照片,如果我进行200px的重采样,图像将不会总是匹配。

答案 1 :(得分:0)

请使用:

$sha1 = sha1_file($img_url);

但在处理图像之前要小心获取sha1! 当用户上传图像时,应根据图像生成所有哈希值,以便将其与未来图像的哈希值进行比较,而无需先进行处理。

请注意!即使您重新缩放图像,保持比例,哈希也会改变。即使您在文本编辑器中打开文件并添加空格,散列也会更改。

将图像缩放到相同宽度的想法可能有效,但前提是它们使用相同的函数或参数进行缩放。它不是100%可信任的。