我正在尝试将图像哈希添加到数据库中。
我的问题是我有300万张图片,其中有些是99.999 +%的图片。例如, imageA.jpg 和 imageB.jpg 的分辨率均为800x600,但是 imageB.jpg 则具有10个不同的像素:>
800x600 =总480000像素;
(480000-10像素差异)/ 48000总像素= 0.9999791666666667相似性
为了减少重复,我编写了PHP类原型。一切都很好,不是很好,但是很好。主要问题是,即使我设置了最高质量,每次-> recreateFile()函数也会创建一点不同的图像。
我正在寻找一种可以稳定所有像素的解决方案,即使我会重新创建图像100次。
还有其他更好的解决方案/想法可以减少重复的图像吗?
我的PHP类代码:
<?php
/**
* Class HashImage
* @package App\Cryptography
*/
class HashImage
{
/**
*
*/
const IMAGE_PIXELS = 32;
/**
*
*/
const IMAGE_QUALITY = 100;
/**
*
*/
const IMAGE_FORMAT = 'jpg';
/**
*
*/
const IMAGE_ALGORITHM = 'sha256';
/**
* @var string
*/
private $file;
/**
* @var
*/
private $hash;
/**
* HashImage constructor.
* @param string $file
*/
public function __construct(string $file)
{
$this->file = $file;
}
/**
* @return string
* @throws \ImagickException
*/
public function getHash(): string
{
$this
->recreateFile()
->setHash(1)
->setHash(2)
->setHash(0);
return hash(self::IMAGE_ALGORITHM, $this->hash);
}
/**
* @param int $type
* @return self
* @throws \ImagickException
*/
private function setHash(int $type): self
{
$image = new \Imagick($this->file);
$image->setImageDepth(8);
$image->setGravity(\Imagick::GRAVITY_CENTER);
$image->quantizeImage(15, \Imagick::COLORSPACE_RGB, 255, false, false);
$image->setImageFormat('PNG');
if ($type === 1) {
$width = self::IMAGE_PIXELS;
$height = self::IMAGE_PIXELS / 2;
} elseif ($type === 2) {
$width = self::IMAGE_PIXELS / 2;
$height = self::IMAGE_PIXELS;
} else {
$width = self::IMAGE_PIXELS;
$height = self::IMAGE_PIXELS;
}
$image->cropThumbnailImage($width, $height);
$img = imagecreatefromstring($image->getImageBlob());
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$colors = imagecolorsforindex($img, imagecolorat($img, $x, $y));
$this->hash .= round((round((round((round(($colors['red'] + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN)
. round((round((round((round(($colors['green'] + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN)
. round((round((round((round(($colors['blue'] + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN) + 1) / 2, 0, PHP_ROUND_HALF_DOWN);
}
}
return $this;
}
/**
* @return self
*/
private function optimizeFile(): self
{
exec('/usr/bin/jpegoptim --strip-all --all-progressive ' . $this->file);
return $this;
}
/**
* @return self
* @throws \ImagickException
*/
private function recreateFile(): self
{
$image = new \Imagick($this->file);
$image->setImageFormat(self::IMAGE_FORMAT);
$image->setCompression(\Imagick::COMPRESSION_JPEG);
$image->setCompressionQuality(self::IMAGE_QUALITY);
$image->writeImage($this->file);
return $this;
}
}
答案 0 :(得分:0)
花了很多时间之后, 当前解决方案代码:
<?php declare(strict_types=1);
namespace App\Cryptography;
/**
* Class HashImage
* @package App\Cryptography
*/
class HashImage
{
/**
* Hashing accuracy
*/
const HASHING_PIXELS = 64;
/**
* Return encryption algorithm
*/
const HASHING_ALGORITHM = 'sha256';
/**
* @var string
*/
private $file;
/**
* @var string
*/
private $hash;
/**
* HashImage constructor.
* @param string $file
*/
public function __construct(string $file)
{
$this->file = $file;
}
/**
* @return string
* @throws \ImagickException
*/
public function getHash(): string
{
$this
->setHash(1)
->setHash(2)
->setHash(0);
return hash(self::HASHING_ALGORITHM, $this->hash);
}
/**
* @param int $type
* @return self
* @throws \ImagickException
*/
private function setHash(int $type): self
{
$image = new \Imagick($this->file);
$image->setImageFormat('PNG');
$image->setImageDepth(8);
$image->setGravity(\Imagick::GRAVITY_CENTER);
$width = $height = self::HASHING_PIXELS;
if ($type === 1) {
$height = self::HASHING_PIXELS / 2;
} elseif ($type === 2) {
$width = self::HASHING_PIXELS / 2;
}
$image->cropThumbnailImage($width, $height);
$img = imagecreatefromstring($image->getImageBlob());
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$colors = imagecolorsforindex($img, imagecolorat($img, $x, $y));
$this->hash .= $colors['red'] . $colors['green'] . $colors['blue'];
}
}
return $this;
}
}