Bagaimana cara menyimpan gambar JPG dalam ruang warna 4:2:0 dengan Imagick?

Google Pagespeed dapat mengonversi gambar RGB ke ruang warna YUV 4:2:0. Saya ingin melakukan hal yang sama di PHP menggunakan imagick.

Secara singkat, mengapa 4:2:0 diinginkan:

"Filter ini mengurangi pengambilan sampel warna gambar jpeg menjadi 4:2:0. Penglihatan manusia jauh lebih sensitif terhadap perubahan kecerahan dibandingkan perubahan rona atau saturasi, dan pengambilan sampel warna 4:2:0 memungkinkan kami menyimpan data kecerahan sekaligus mengurangi jumlah data rona dan saturasi sebesar 3/4. Hal ini dapat mengurangi ukuran gambar secara signifikan namun hanya memberikan sedikit pengaruh pada persepsi."

Saya telah mencoba mengubah ruang warna dengan imagemagick ke YUV tetapi tidak berfungsi sama sekali! Latar belakang putih berubah menjadi hijau dan warna lainnya salah, ditambah pencahayaan terbalik.

Kode berikut tidak berguna, tetapi ini menunjukkan beberapa hal yang telah saya coba.

Dengan format Google yang dibuat oleh mod_pagespeed gambar yang dihasilkan terlihat bagus di browser. Itulah yang ingin saya capai, gambar untuk web.

    $image_info = getimagesize($source_file);
    $im = new Imagick();
    $im->readImage($source_file);
    $profiles = $im->getImageProfiles('*', false);
    $has_icc_profile = (array_search('icc', $profiles) !== false);
    if ($has_icc_profile === false) {
        $icc_srgb = file_get_contents(Mage::getBaseDir('var') . DS . 'metodo' . DS . 'demo_data' . DS . 'AdobeRGB1998.icc');
        $im->profileImage('icc', $icc_srgb);
        unset($icc_srgb);
    }
    //$im->setImageColorspace(1);
    $im->setInterlaceScheme(Imagick::INTERLACE_PLANE);
    $im->setImageCompressionQuality(85);
    //$im->stripImage(); 
    $im->setImageColorspace(11);
    $im->thumbnailImage($this->_imageSrcWidth, $this->_imageSrcHeight);
    //$im->negateImage(false, Imagick::CHANNEL_ALL);
    $im->stripImage();
    $im->writeImage($fileName);

person Henry's Cat    schedule 25.11.2014    source sumber
comment
4:2:0 bukan ruang warna, melainkan tipe subsampling chrome. Anda mungkin harus melihat Imagick::setSamplingFactors. Namun, dokumentasi PHP tidak memiliki penjelasan apa pun tentang isi argumen tunggal metode itu, dan saya benar-benar tidak tahu...   -  person Plenka    schedule 25.11.2014


Jawaban (2)


Saya tertarik dengan kurangnya dokumentasi tentang metode Imagick::setSamplingFactors (lihat komentar saya), jadi Saya mencoba mencari tahu.

Dengan menggunakan metode Imagick::identifyImage menjadi jelas bahwa perpustakaan Imagick tidak menggunakan notasi 4:2:0 untuk subsampling kroma, tetapi sesuatu seperti '1x1,1x1,1x1'. Di http://www.ftgimp.com/help/C/filters/jpeg.html (20180608: tidak tersedia lagi, diarsipkan di sini) sudah jelas bahwa '1x1,1x1,1x1' diterjemahkan menjadi 4:4:4, dan '2x2,1x1,1x1' diterjemahkan menjadi 4:2:0. Karena metode Imagick::setSamplingFactors memerlukan array sebagai argumennya, saya mencoba yang berikut ini, yang berhasil:

$img = new Imagick($source_file)
$img->setSamplingFactors(array('2x2', '1x1', '1x1'));
$im->writeImage($fileName);
person Plenka    schedule 26.11.2014
comment
Jawaban yang bagus - dokumentasi PHP dapat diedit oleh siapa saja. Apakah Anda suka meletakkan jawaban ini di sana? - person Danack; 26.11.2014
comment
Ini semakin dekat!!! Saya benar-benar senang dengan jawaban Anda yang menginspirasi, saat ini saya hanya tinggal 'beberapa upaya lagi' untuk mewujudkannya. Ini akan berhasil!!! Saya telah mencoba dalam kode saya untuk memperkecil file dengan cara ini - dan masuk ke identifikasi -verbose untuk melihat apa yang terjadi. Terima kasih banyak telah menjelaskan lebih lanjut pada pertanyaan ini, saya yakin Anda benar tetapi belum ada tanda centang hijau!!! - person Henry's Cat; 26.11.2014
comment
@Danack, tidak yakin saya cukup berpengetahuan. Pertanyaan itu menarik minat saya, jadi saya menggali setSamplingFactors. Seperti yang saya katakan, kurangnya dokumentasilah yang membuat saya penasaran untuk menggali lebih dalam, tetapi yang saya tahu hanyalah jawaban itu. Mempercepat teori untuk menyediakan dokumentasi yang tepat agak berlebihan bagi saya. Wolfie, kuharap ini terobosanmu. :) - person Plenka; 26.11.2014

Mungkin secara teknis bukan jawaban, tetapi terlalu canggung untuk diformat sebagai komentar, dan ini mungkin membantu menemukan jawabannya.

Anda dapat melakukan hal semacam ini yang mungkin memberikan beberapa wawasan tentang cara menggunakan parameter dan apa fungsinya:

convert input.jpg -colorspace YUV out.jpg
convert input.jpg -colorspace YUV -sampling-factor 4:2:2 out442.jpg
convert input.jpg -colorspace YUV -sampling-factor 4:2:0 out420.jpg

kemudian Anda dapat melihat ukuran file yang dihasilkan untuk berbagai pengaturan. Tampaknya ukuran file keluaran berkorelasi cukup baik dengan pengambilan sampel, dan pengambilan sampel default IM adalah 4:4:4 karena cocok dengan ukurannya ketika saya tidak memberikan -sampling-factor apa pun:

ls -l out*
-rw-r--r--  1 mark  staff  105563 26 Nov 10:23 out.jpg
-rw-r--r--  1 mark  staff   77230 26 Nov 10:23 out410.jpg
-rw-r--r--  1 mark  staff   81755 26 Nov 10:24 out411.jpg
-rw-r--r--  1 mark  staff   82835 26 Nov 10:23 out420.jpg
-rw-r--r--  1 mark  staff  105563 26 Nov 10:25 out444.jpg

tautan ini dapat membantu.

person Mark Setchell    schedule 26.11.2014