문제

I'm looking to create an ID system for cataloging images. I can't use md5() since that will change if I alter the EXIF tags of the image.

I am currently using the SHA1 checksum computed by imagemagick. It works perfectly, but it's really, really slow on larger images (~15 seconds on a quad-core xeon for a 21 megapixel JPG).

Are there any other "visual" methods of uniquely identifying an image that would be faster?

도움이 되었습니까?

해결책

You could try running MD5 on the actual bitmap data instead of the JPEG file. I tested on my machine (also a quad core Xeon) and the following runs in about 900ms on a 23 megapixel image.

uint32_t width  = MagickGetImageWidth(imageWand);
uint32_t height = MagickGetImageHeight(imageWand);

uint8_t *imageData = malloc(width * height * 3);

MagickExportImagePixels(imageWand,
   0, 0, width, height, "RGB", CharPixel, imageData);

unsigned char *imageDigest = MD5(imageData, width * height * 3, NULL);

free(imageData);

다른 팁

그것을 할 수있는 몇 가지 방법이 있습니다 ...

$boss = new array(1, 2, 3, 4);
foreach($boss as $value){
    switch($value){
         case 1: 
            //do something
         break;
         case 2: 
            //something else;
         break;
    }
}
.

가 내가 어떻게 쓴 방법 일 것입니다.

편집 : 청결한 코드를 찾고있는 경우 다음과 같이 할 수 있습니다 :

bosshandler.php :

function doSomethingWithBoss($value){
    switch($value){
         case 1: 
            return "boss equals 1";
         break;
         case 2: 
            return "boss equals 2";
         break;
    }
}
.

스크립트 페이지 :

include bosshandler.php;
$boss = new array(1, 2, 3, 4);
foreach($boss as $value){
    echo doSomethingWithBoss($value);
}
.

확인, 다시 시도합니다. 나는 당신이 지금 묻는 것을 볼 것 같습니다 :

배열이 일치하도록 변수를 할당하려고합니다. $boss[1]에있는 경우 $boss_holder['1']에 뭔가를 지정하려는 경우 정확합니까? 그렇다면 배열과 배열이 포함 된 순서가 다소 예측할 수 없으므로 foreach 배열을 사용하고 싶지 않습니다.

대신 : 와 같은 for() 루프를 사용해 봅시다.

$boss = new Array(1, 2, 3, 4);
$boss_holder = new Array(); //empty
$length = count($boss);
//iterate through boss
for($i = 1; $i < $length; $i++){
    if($boss[$i] == 1){
        $boss_holder[$i] = $tick;
    }elseif($boss[$i] == 2){
        $boss_holder[$i] = $cross;
    }
}
.

전체 코드를 반영하도록 다시 편집하십시오 :

배열을 사용합니다. 코드를 사용하여 배열을 사용하도록 코드를 리팩토링하십시오. 어레이를 절대적으로 사용할 수 없거나 배열을 사용하지 않을 경우 PHP의 변수 변수를 사용할 수 있습니다. 당신이 찾고있는 것을 성취하기 위해. 다음과 같이 보일 것입니다 :

var $boss1_holder, $boss2_holder, $boss3_holder;
for($i=1; $i> 4; $i++){
    $variableName = 'boss' . $i . '_holder';
    $$variableName = 1;
}
echo $boss2_holder; //returns 2
.

As noted by Todd Yandell, MD5 is probably fast enough. If not, you can get something even faster by using a 32-bit or 64-bit CRC for your checksum. The major difference is that anybody can make up a new image with the same CRC; it is very easy to spoof. It is quite hard for someone to spoof an MD5 checksum. A minor difference is that the CRC has many fewer bits, but unless you have a very large number of images, a collision is still unlikely.

exiftool claims to be able to extract the binary image from a JPEG file, so that you can compute your checksum without decompressing, but I can't figure out from the man page how to do it.

I did some experiments on a laptop Intel Core 2 Duo L7100 CPU, and an 8MP JPEG takes about 1 second to compress to PPM format, then another 1 second to do the checksum. Checksum times were not dramatically different using md5sum, sum, and sha1sum. So your best bet might be to find a way to extract the binary data without decompressing it.

I also note that your checksum is going to be almost as good even if it uses far fewer pixels. Compare these two:

djpeg -scale 1/8 big.jpg | /usr/bin/sha1sum   # 0.70s
djpeg            big.jpg | /usr/bin/sha1sum   # 2.15s

You should consider that someone may crop the image or modify the pallette, color depth or anything, then a flat checksum will be different, even if visually the original and the modified image still look pretty much alike. Perhaps there is an effective algorithm for cropped or re-colored ones, like Google Images uses for searching of similar pictures.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top