PHP:如何检测jpeg是否完全黑(没有图像)?

时间:2011-01-31 15:52:47

标签: php gd

我建立了一个社区网站,用户可以上传他们的照片,他们可以裁剪缩略图,Facebook很清楚。

但由于某种原因,他们中的一些会产生一个空白(实际上是黑色的jpeg缩略图)。

我尝试了不同的解决方案,但听起来这种情况发生在大图片上,或者可能是在未启用JS的计算机中?我不知道......

最重要的是,由于用户数量很少,我想创建一个补丁:检测用户何时生成空白jpeg。然后我就可以发出警告。

你知道怎么做吗?

7 个答案:

答案 0 :(得分:5)

将其调整为1x1 PX图像。然后检查一个像素是否为黑色。不完美,但如果原版中有非常大量的非黑色,则1px不会是黑色。好处是它会很快。

答案 1 :(得分:3)

认为没有比使用imagecolorat().

走过每个像素更快的方法了

至于为什么会发生这种情况,可能是因为GD无法消化的CMYK JPG文件。不确定 - 你必须试试。如果这是原因,您可以使用getimagesize()及其channels信息检测CMYK。

答案 2 :(得分:2)

我喜欢这个随意的算法,

function check_if_black($src){

    $img = imagecreatefromjpeg($src);
    list($width_orig, $height_orig)=getimagesize($src);
    for($i=0;$i<20;$i++){
        $rand_width=rand ( 0 , $width_orig );
        $rand_height=rand ( 0 , $height_orig );
        $rgb = imagecolorat($img, $rand_width, $rand_height);
        if($rgb!=0){
            return "not black";
        }
    }
    return "black";
}

即使80%的图像是黑色的,它也有99%的成功。你也可以增加循环以获得更好的百分比。

答案 3 :(得分:1)

假设它是一个有效的黑色图像,你可以:

很长的路 - 逐个像素地扫描黑色

简短的方法(如果它始终是相同的黑色图像) - 将文件逐字节(或md5哈希)与样本黑色图像进行比较

答案 4 :(得分:1)

如果所有缩略图的大小都相同,请举一个简单的示例:

// b3122965acb460720824611e8e17b960 = 64x64 black image

if (md5(file_get_contents("images/test.jpg")) == "b3122965acb460720824611e8e17b960")
{
  echo "Black image";
}

答案 5 :(得分:0)

这是我的代码:

<?php

namespace App\Traits;

trait BlacknessCheck {

    public static function fileIsBlack($filename, $throw_error = false) {

        if (exif_imagetype($filename) === IMAGETYPE_JPEG) {

            return self::imageIsBlack(imagecreatefromjpeg($filename));

        } elseif ($isimage === IMAGETYPE_PNG) {

            return self::imageIsBlack(imagecreatefrompng($filename));

        } else {

            if ($throw_error) {
                throw new \Exception("Provided file is not an image.");
            } else {
                return false;
            }

        }

    }

    public static function imageIsBlack($image) {

        $scaled_image = self::scaleImage($image);

        $added_colors =
            imagecolorat($scaled_image, 0, 0) +
            imagecolorat($scaled_image, 0, 1) +
            imagecolorat($scaled_image, 0, 2) +
            imagecolorat($scaled_image, 1, 0) +
            imagecolorat($scaled_image, 1, 1) +
            imagecolorat($scaled_image, 1, 2) +
            imagecolorat($scaled_image, 2, 0) +
            imagecolorat($scaled_image, 2, 1) +
            imagecolorat($scaled_image, 2, 2);

        imagedestroy($scaled_image);
        imagedestroy($image);

        return ($added_colors === 0);

    }

    public static function scaleImage($image) {
        $newimage = imagecreatetruecolor(3, 3);
        imagecopyresampled(
            $newimage, $image,
            0, 0, 0, 0,
            3, 3, imagesx($image), imagesy($image)
        );
        return $newimage;
    }

}

我正在用它去除黑拇指。

private function removeBlackness() {

    $files = $this->glob_recursive(public_path('img/collection/*.jpg'));
    foreach ($files as $filename) {

        if (self::fileIsBlack($filename)) {
            unlink($filename);
        }

    }

}

答案 6 :(得分:-1)

如果全黑,则文件大小会很低,因为它是压缩的。我知道JPG使用感知而不是RLE,但它仍然会更小。例如,为什么不禁止低于20k的JPG?举几个例子,比较尺寸,设定你的门槛。