Цвет изображения разрушен при изменении размера изображения с помощью imagecopyresampled

После загрузки изображений на мой сайт изображения изменяются. Я использую функции imagecreatefromjpeg и imagecopyresampled. Я заметил, что цвет отличается от исходного изображения.

Здесь вы можете увидеть разницу. Вы можете видеть изображение из мерцания с помощью правильных цветов и позади изображения с моего сайта. Пример

Исходное изображение: https://c2.staticflickr.com/6/5754/23693488109_74c67f012a_k.jpg

После rsizing: https://www.isrart.co.il/img/uploads/art/viewer/big/photo-2b971e861c7aa2c57b8f7667ec666c3d.jpg

Вот мой PHP-код:

    $type = @getImageSize($_FILES['photo']['tmp_name'])[2];
    switch ($type) { 
        case 1 : 
            $img = imageCreateFromGif($_FILES['photo']['tmp_name']); 
        break; 
        case 2 : 
            $img = imageCreateFromJpeg($_FILES['photo']['tmp_name']); 
        break; 
        case 3 : 
            $img = imageCreateFromPng($_FILES['photo']['tmp_name']); 
        break; 
        case 6 : 
            $img = imageCreateFromBmp($_FILES['photo']['tmp_name']); 
        break; 
    }    

    $orig_width = imagesx($img);
    if($orig_width < $width)
        return $img;

    $orig_height = imagesy($img);

    $height = (($orig_height * $width) / $orig_width);

    $new_image = imagecreatetruecolor($width, $height);

    imagecopyresampled($new_image, $img, 0, 0, 0, 0, $width, $height, $orig_width, $orig_height);

    imagejpeg($new_image, $_SERVER['DOCUMENT_ROOT'] . "/img/uploads/" . $path, 100);

Ответы

Ответ 1

Ваше исходное изображение имеет связанный с ним профиль ICC размером 560 байт, тогда как ваше повторно сэмплированное изображение не работает.

Вы можете извлечь профиль из исходного изображения с помощью ImageMagick следующим образом:

convert orig.jpg profile.icm

Вы можете увидеть это здесь, если я разберу два файла:

введите описание изображения здесь

Замечу, что если я переконструирую исходное изображение в командной строке с помощью ImageMagick, вот так:

convert orig.jpg -resize 1110x1570! myresampled.jpg

то профиль ICC переносится вперед. Я могу проверить следующее:

identify -verbose orig.jpg myresampled.jpg | grep -i profile

  Profiles:
    Profile-icc: 560 bytes
  Profiles:
    Profile-icc: 560 bytes

Ответ 2

Я уверен, что это PNG файл, и в нем есть кусок информации, называемый "gAMA". Это своего рода гамма-коррекция, некоторые зрители ее используют, а некоторые нет. При загрузке изображения библиотека GD игнорирует эту информацию. Но Imagick должен сделать трюк:

http://php.net/manual/en/imagick.getimageproperties.php

Надеюсь, что это поможет.

Ответ 3

Причина, по которой сжатое изображение выглядит скучным по сравнению с оригиналом, связано с его цветовым форматом. В оригинале используется субсэмплин 4: 4: 4, а сжатый - 4: 2: 0. Это приводит к потере информации о цвете.

Используемый инструмент mediainfo для чтения метаданных изображений

Чтобы преодолеть это, мы можем сделать это масштабирование с помощью ffmpeg или avconv и которые могут быть выполнены из оболочки в PHP.

Я создал качественное масштабированное изображение с использованием avconv со следующими двумя командами.

avconv -i Input.jpg -pix_fmt yuvj444p -vf scale=1110:1570 Output.yuv

avconv -y -s 1110x1570 -f rawvideo -pix_fmt yuv444p -i Output.yuv Output.jpg