Grafika\Gd\Filter\Dither::diffusion PHP Method

diffusion() private method

Dither using error diffusion.
private diffusion ( Image $image ) : Image
$image Grafika\Gd\Image
return Grafika\Gd\Image
    private function diffusion($image)
    {
        $pixel = array();
        // Localize vars
        $width = $image->getWidth();
        $height = $image->getHeight();
        $old = $image->getCore();
        $new = imagecreatetruecolor($width, $height);
        for ($y = 0; $y < $height; $y += 1) {
            for ($x = 0; $x < $width; $x += 1) {
                $color = imagecolorat($old, $x, $y);
                $r = $color >> 16 & 0xff;
                $g = $color >> 8 & 0xff;
                $b = $color & 0xff;
                $gray = round($r * 0.3 + $g * 0.59 + $b * 0.11);
                if (isset($pixel[$x][$y])) {
                    // Add errors to color if there are
                    $gray += $pixel[$x][$y];
                }
                if ($gray <= 127) {
                    // Determine if black or white. Also has the benefit of clipping excess val due to adding the error
                    $blackOrWhite = 0;
                } else {
                    $blackOrWhite = 255;
                }
                $oldPixel = $gray;
                $newPixel = $blackOrWhite;
                // Current pixel
                imagesetpixel($new, $x, $y, imagecolorallocate($new, $newPixel, $newPixel, $newPixel));
                $qError = $oldPixel - $newPixel;
                // Quantization error
                // Propagate error on neighbor pixels
                if ($x + 1 < $width) {
                    $pixel[$x + 1][$y] = (isset($pixel[$x + 1][$y]) ? $pixel[$x + 1][$y] : 0) + $qError * (7 / 16);
                }
                if ($x - 1 > 0 and $y + 1 < $height) {
                    $pixel[$x - 1][$y + 1] = (isset($pixel[$x - 1][$y + 1]) ? $pixel[$x - 1][$y + 1] : 0) + $qError * (3 / 16);
                }
                if ($y + 1 < $height) {
                    $pixel[$x][$y + 1] = (isset($pixel[$x][$y + 1]) ? $pixel[$x][$y + 1] : 0) + $qError * (5 / 16);
                }
                if ($x + 1 < $width and $y + 1 < $height) {
                    $pixel[$x + 1][$y + 1] = (isset($pixel[$x + 1][$y + 1]) ? $pixel[$x + 1][$y + 1] : 0) + $qError * (1 / 16);
                }
            }
        }
        imagedestroy($old);
        // Free resource
        // Create new image with updated core
        return new Image($new, $image->getImageFile(), $width, $height, $image->getType());
    }