PHP:如何检测jpeg是否为完全黑色(无图像)?

PHP:如何检测jpeg是否为完全黑色(无图像)?,php,gd,Php,Gd,我建立了一个社区网站,用户可以上传他们的照片,他们可以裁剪缩略图,让Facebook变得清晰 但由于某些原因,其中一些会生成一个空白(实际上是黑色jpeg缩略图) 我尝试了不同的解决方案,但这听起来像是发生在大图像上,或者是在没有启用JS的计算机上?我不知道 一句话,由于使用此功能的用户数量非常少,我正在考虑创建一个补丁:检测用户何时生成一个空白jpeg,然后我就可以向他们发出警告 你知道怎么做吗?假设它是有效的黑色图像,你可以: 长距离-逐像素扫描黑色 短途(如果始终是相同的黑色图像)-将文件

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

但由于某些原因,其中一些会生成一个空白(实际上是黑色jpeg缩略图)

我尝试了不同的解决方案,但这听起来像是发生在大图像上,或者是在没有启用JS的计算机上?我不知道

一句话,由于使用此功能的用户数量非常少,我正在考虑创建一个补丁:检测用户何时生成一个空白jpeg,然后我就可以向他们发出警告


你知道怎么做吗?

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

长距离-逐像素扫描黑色

短途(如果始终是相同的黑色图像)-将文件逐字节(或md5哈希)与示例黑色图像进行比较

我认为没有比使用


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

如果全黑,则压缩后的文件大小将较低。我知道JPG使用感知而不是RLE,但它仍然会更小。例如,为什么不允许低于20k的JPG?举几个例子,比较大小,设置阈值

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

我喜欢这种随机算法

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";
}
函数检查如果为黑色($src){
$img=imagecreatefromjpeg($src);
列表($width\u orig,$height\u orig)=getimagesize($src);
对于($i=0;$i,以下是我的代码:

<?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;
    }

}

第二个选项不起作用。你需要为宽度、高度、压缩比、编解码器的每一个组合提供一个单独的副本…我不认为短的方法会起作用,因为ID3头和其他元数据将一直存在巨大差异…但我可能错了。字节计数/内容是否会根据文件大小而有所不同?@Joe@Pekka我假设为fixed宽度/高度/id3剥离jpeg:)@reuscam我们不知道这一点。捷径只是一个想法,以防它对OP有效。这听起来是个坏主意。我想上传一些灰色薄雾吗?那么海报可能不希望你出现在他的网站上!包括那些黑色图像?Jpeg压缩波。因此梯度也会导致文件大小变小。云层将压缩为l文件大小和棋盘格会压缩得很好。这个问题是关于黑色图像的。可能是损坏的图像。我的建议是将图像重采样为1或3x3像素,并添加所有重采样像素的RGB值。只有黑色图像的结果为0。有趣的想法,但我认为1x1太粗糙了。这是bound用于创建假负片,例如使用棋盘格或黑白几何形状。但这可能适用于10x10像素image@pekka没错,10x10可能更准确,而且速度也相当快。这是一个不错的折衷办法。@Pekka웃 棋盘格的重采样(抗锯齿)缩放图像将变为灰色。
private function removeBlackness() {

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

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

    }

}