ฉันจะบันทึกรูปภาพ JPG ในพื้นที่สี 4:2:0 ด้วย Imagick ได้อย่างไร

Google Pagespeed สามารถแปลงภาพ RGB เป็นพื้นที่สี YUV 4:2:0 ฉันต้องการทำเช่นเดียวกันใน PHP โดยใช้ imagick

โดยสรุปว่าทำไมถึงต้องการ 4:2:0:

"ฟิลเตอร์นี้ลดตัวอย่างสีของภาพ JPEG เป็น 4:2:0 การมองเห็นของมนุษย์ไวต่อการเปลี่ยนแปลงความสว่างมากกว่าการเปลี่ยนแปลงของสีหรือความอิ่มตัวของสี และการสุ่มตัวอย่างสี 4:2:0 ช่วยให้เราสามารถเก็บข้อมูลความสว่างในขณะที่ลดขนาดลง ปริมาณข้อมูลเฉดสีและความอิ่มตัวของสี 3/4 ซึ่งสามารถลดขนาดภาพลงได้อย่างมากในขณะที่มีผลกระทบเพียงเล็กน้อยต่อการรับรู้"

ฉันได้ลองเปลี่ยนสเปซสีด้วย imagemagick เป็น YUV แล้ว แต่มันทำงานได้ไม่ดีเลย! ฉากหลังสีขาวกลายเป็นสีเขียวและสีอื่นๆ ผิด บวกกับความสว่างแบบกลับด้าน

รหัสต่อไปนี้ไม่มีประโยชน์ แต่แสดงบางสิ่งที่ฉันได้ลองแล้ว

ด้วยรูปแบบของ Google ที่สร้างโดย mod_pagespeed รูปภาพที่ได้จะดูดีในเบราว์เซอร์ นั่นคือสิ่งที่ฉันหวังว่าจะบรรลุผลสำเร็จ รูปภาพที่มีไว้สำหรับเว็บ

    $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 แหล่งที่มา
comment
4:2:0 ไม่ใช่สเปซสี แต่เป็น ประเภทการสุ่มตัวอย่างโครมา. คุณน่าจะดูที่ Imagick::setSamplingFactors อย่างไรก็ตาม เอกสาร PHP ขาดคำอธิบายใด ๆ ว่าเนื้อหาของอาร์กิวเมนต์เดียวของวิธีการนั้นควรเป็นอย่างไร และฉันก็ไม่มีเบาะแสจริงๆ...   -  person Plenka    schedule 25.11.2014


คำตอบ (2)


ฉันรู้สึกทึ่งมากที่ไม่มีเอกสารประกอบเกี่ยวกับเมธอด Imagick::setSamplingFactors (ดู ความคิดเห็นของฉัน) ดังนั้น ฉันพยายามคิดออก

การใช้เมธอด Imagick::identifyImage เป็นที่ชัดเจนว่าไลบรารี Imagick ไม่ได้ใช้สัญกรณ์ 4:2:0 สำหรับการสุ่มตัวอย่างโครมา แต่ใช้บางอย่างเช่น '1x1,1x1,1x1' ที่ http://www.ftgimp.com/help/C/filters/jpeg.html (20180608: ไม่มีอีกต่อไป เก็บถาวรไว้ที่นี่) ทำให้ชัดเจนว่า '1x1,1x1,1x1' แปลเป็น 4:4:4 และ '2x2,1x1,1x1' เป็น 4:2:0 เนื่องจากเมธอด Imagick::setSamplingFactors ต้องใช้อาร์เรย์เป็นอาร์กิวเมนต์ ฉันจึงลองทำสิ่งต่อไปนี้ ซึ่งได้ผลสำเร็จ:

$img = new Imagick($source_file)
$img->setSamplingFactors(array('2x2', '1x1', '1x1'));
$im->writeImage($fileName);
person Plenka    schedule 26.11.2014
comment
คำตอบที่ดี - ทุกคนสามารถแก้ไขได้ในเอกสาร PHP คุณอยากจะใส่คำตอบนี้ไว้ตรงนั้นไหม? - person Danack; 26.11.2014
comment
นี่ใกล้จะถึงแล้ว!!! ฉันรู้สึกยินดีเป็นอย่างยิ่งกับคำตอบที่ได้รับการดลใจของคุณ ตอนนี้ฉันแค่ 'พยายามอีกสองสามครั้ง' เพื่อทำให้สิ่งนี้ได้ผล มันจะทำงาน!!! ฉันได้ลองใช้โค้ดของฉันเพื่อให้ไฟล์มีขนาดเล็กลงด้วยวิธีนี้ - และเข้าไประบุ -verbose เพื่อดูว่าเกิดอะไรขึ้น ขอบคุณมากที่ตอบคำถามนี้เพิ่มเติม ฉันแน่ใจว่าคุณพูดถูกแต่ยังไม่มีเครื่องหมายสีเขียว!!! - person Henry's Cat; 26.11.2014
comment
@Danack ไม่แน่ใจว่าฉันมีความรู้เพียงพอ คำถามนี้จุดประกายความสนใจของฉัน ดังนั้นฉันจึงขุด setSamplingFactors ขึ้นมา อย่างที่ฉันบอกไปแล้วว่าการขาดเอกสารทำให้ฉันสนใจที่จะเจาะลึกลงไป แต่สิ่งที่ฉันรู้ก็คือคำตอบนั้น การก้าวตามทฤษฎีให้ทันเพื่อให้เอกสารประกอบที่เหมาะสมนั้นมากเกินไปสำหรับฉันเล็กน้อย วูล์ฟฟี่ ฉันหวังว่ามันจะเป็นความก้าวหน้าของคุณ :) - person Plenka; 26.11.2014

อาจไม่ใช่คำตอบในทางเทคนิค แต่อึดอัดเกินไปที่จะจัดรูปแบบเป็นความคิดเห็น และอาจช่วยค้นหาคำตอบได้

คุณสามารถทำสิ่งนี้ซึ่งอาจให้ข้อมูลเชิงลึกเกี่ยวกับวิธีใช้พารามิเตอร์และสิ่งที่พวกเขาดูเหมือนจะทำ:

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

จากนั้นคุณจะเห็นขนาดไฟล์ผลลัพธ์สำหรับการตั้งค่าต่างๆ ดูเหมือนว่าขนาดไฟล์เอาต์พุตจะสัมพันธ์กันค่อนข้างดีกับการสุ่มตัวอย่าง และการสุ่มตัวอย่างเริ่มต้นของ IM คือ 4:4:4 เนื่องจากมันตรงกับขนาดเมื่อฉันไม่ได้ระบุ -sampling-factor ใดๆ:

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

ลิงก์นี้อาจช่วยได้

person Mark Setchell    schedule 26.11.2014