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

发布于 2024-10-15 01:23:19 字数 249 浏览 3 评论 0原文

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

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

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

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

你知道该怎么做吗?

I built a community website where the users upload their photo and they can crop the thumbnail, ala Facebook to be clear.

But for some reason some of them generate a blank (actually black jpeg thumbnail).

I tried different solutions but it sounds like this is happening with big images or maybe in computers where JS is not enabled? I don't know...

Bottom line, since the number of users with this is very tiny, I was thinking of creating a patch: detect when the user generates a blank jpeg.Then I would be able to warn them.

Do you know how to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

岁月苍老的讽刺 2024-10-22 01:23:19

将其大小调整为 1x1 PX 图像。然后检查该像素是否为黑色。并不完美,但如果原图中有大量非黑色,那么 1px 将不会是黑色。好处是速度会很快。

Resize it to a 1x1 PX image. Then check if the one pixel is black. Not perfect, but if there is a significant amount of non black in the original, that 1px will not be black. The benefit is that it will be fast.

灯下孤影 2024-10-22 01:23:19

我认为没有比使用 imagecolorat().

至于为什么会出现这种情况,可能是因为CMYK JPG 文件。不确定 - 你必须尝试一下。如果这是原因,您可以使用 getimagesize() 检测 CMYK 及其频道 信息。

I think there is no faster way than walking though each pixel using imagecolorat().

As to why this happens, it could be because of CMYK JPG files that GD can't digest. Not sure - you would have to try out. If that is the reason, you could detect CMYK using getimagesize() and its channels info.

っ左 2024-10-22 01:23:19

我喜欢这种随机算法,

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% 的成功率。您还可以增加循环以获得更好的百分比。

I like this random algoritm,

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

Even if 80% of the image is black it has 99% to succeed. you can also increase the loop for better percentage.

旧城烟雨 2024-10-22 01:23:19

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

长方式 - 逐像素扫描黑色

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

Assuming its a valid black image you could:

long way - scan pixel by pixel for the colour black

short way (if its the same black image always) - compare file byte by byte (or md5 hash) to a sample black image

怪异←思 2024-10-22 01:23:19

这是我的代码:

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

    }

}

Here is my code:

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

}

I'm using it to remove black thumbs.

private function removeBlackness() {

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

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

    }

}
月竹挽风 2024-10-22 01:23:19

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

If it's all black, the file size will be low, as it's compressed. I know JPG uses perceptual rather than RLE, but it will still be smaller. Why not disallow JPGs under 20k for example? Make a few examples, compare the sizes, set your thresholds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文