Делаем черно-белое изображение из цветного средствами php — 3 способа

Недавно один мой хороший друг спросил как быстро на php цветные изображения сделать черно-белыми. Порывшись бегло в интернете нашел несколько решений, в некоторых кое-что подкорректировал, и решил проверить как это все работает заодно по скорости.

Первым способом решается эта проблема с помощью функции imagecopymergegray. Она не совсем для этого, а скорее для переноса части одной картинки на другую с установленным коэфициентом прозрачности. Для получения черно-белого изображения используется следующий код

$dest = imagecreatefrompng($img_src);
$src = $dest;

$imageSize = getimagesize($img_src);
imagecopymergegray($dest, $src, 0, 0, 0, 0, 0, 0, 0);
imagepng($dest,'result.png' );

imagedestroy($dest);
imagedestroy($src);

Где $img_src это путь к исходному изображению.

Второй способ наиболее правильный, как мне кажется, ибо используется функционал предназначенный именно для создания черно-белых изображений. К слову, забегая вперед, скажу, что это еще и наиболее быстрый и наименее ресурсоемкий способ из рассматриваемых.

$image = imagecreatefrompng($img_src);
imagefilter($image, IMG_FILTER_GRAYSCALE);
imagepng($image,'result.png' );
imagedestroy($image);

Третий способ исключительно для ознакомления, как-никак на кафедре родного университета часто приходилось разрабатывать ПО для обработки графики, в частности изображений со спутника, который так и не взлетел. В данном способе идет попиксельная обработка и приведение к черно-белой палитре изображения.

$original = imagecreatefrompng($img_src); 

$im = imagecreate(imagesx($original), imagesy($original)); 

for ($i = 0; $i <= 255; $i++) {
    $palette[$i] = imagecolorallocate($im, $i, $i, $i);
} 

function grayscale($r, $g, $b) {
    return 0.199*$r + 0.587*$g + 0.114*$b;
} 

for($x = 0; $x < imagesx($original); $x++) {
    for($y = 0; $y < imagesy($original); $y++) {
        $rgb = imagecolorat($original, $x, $y);
        $r = ($rgb >> 16) & 0xFF;
        $g = ($rgb >> 8 ) & 0xFF;
        $b = $rgb & 0xFF;
        imagesetpixel($im, $x, $y, $palette[grayscale($r, $g, $b)]);
    }
} 

imagepng($im, 'result.png');

Теперь о скорости: первый и второй способ можно назвать быстрыми 0,4 и 0,3 секунды тратят они соответственно на генерацию черно-белого изображения. Третий способ, само-собой разумеется наиболее тяжелый — выполнялся около 3,5 секунд.