Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can PHP Detect if an Image is "Too Light'?

Tags:

php

In a certain area of an educational website, students scan and submit their homework.

Problem: When students use pencil, the scans end up being very light and hard to read.

Can PHP be used to some how detect if a scan is too light? I'm wondering if something like Detecting colors for an Image using PHP or maybe How to detect "light" colors with PHP could be used, but I'm not sure. Thus the question.

I'm not asking for code necessarily, just seeing if it's possible and if there's some kind of function that already exists for this sort of thing.

UPDATE BASED ON h2ooooooo's ACCEPTED ANSWER

I'm wondering if PNG bit depth is causing a problem here. Using his (her?) solution, consider the following...

This image ("1.png") returns 97.8456638355 and has a bit depth of 32...

However, this image ("2.png") returns 98.4853859241 and has a bit depth of 24...

This is a difference of less than 1% and it seems like the 1.png should return with a lower number as it is significantly "crisper" and overall is darker than 2.png.

Does anyone have an idea if bit depth is causing the script to not work correctly?

like image 202
gtilflm Avatar asked Feb 05 '14 14:02

gtilflm


1 Answers

Something as simple as the following should work, simply going through every pixel and using the HSL algorithm in the thread you linked. For your purpose, you can simply take the value and compare it to a threshold (test various documents!).

Code:

<?php
    function getBrightness($gdHandle) {
        $width = imagesx($gdHandle);
        $height = imagesy($gdHandle);

        $totalBrightness = 0;

        for ($x = 0; $x < $width; $x++) {
            for ($y = 0; $y < $height; $y++) {
                $rgb = imagecolorat($gdHandle, $x, $y);

                $red = ($rgb >> 16) & 0xFF;
                $green = ($rgb >> 8) & 0xFF;
                $blue = $rgb & 0xFF;

                $totalBrightness += (max($red, $green, $blue) + min($red, $green, $blue)) / 2;
            }
        }

        imagedestroy($gdHandle);

        return ($totalBrightness / ($width * $height)) / 2.55;
    }
?>

Usage:

<?php
    var_dump( getBrightness( imagecreatefrompng('pic1.png') ) ); 
    // 22.626517105341

    var_dump( getBrightness( imagecreatefrompng('pic2.png') ) ); 
    // 60.289981746452

    var_dump( getBrightness( imagecreatefrompng('pic3.png') ) ); 
    // 77.183088971324
?>

Results:

pic1.png (22.62% bright):

enter image description here

pic2.png (60.28% bright):

enter image description here

pic3.png (77.18% bright):

enter image description here

NOTE:

This will take a very long time if the document is huge (it'll iterate through EVERY pixel). If you wish for it to be quicker, you can always pass a resized GD resource to the function instead.

like image 138
h2ooooooo Avatar answered Oct 12 '22 19:10

h2ooooooo