ในการพัฒนาเว็บแอปส่วนใหญ่ เรามักจะจำเป็นต้อง
จัดการกับไฟล์รูปภาพ โดยเฉพาะกับไฟล์ที่ได้ทำการ
อัพโหลดไปใช้งาน เช่น การสร้าง thumbnail ในขนาด
ต่างๆ ไว้ใช้งาน การปรับขนาดของรูปให้เป็นไปตามข้อ
จำกัดที่กำหนด การใส่ลายน้ำ เหล่านี้เป็นต้น
เราสามารถนำ library หรือ package ต่างๆ มาใช้งาน
เพื่อจัดการกับรูปภาพร่วมกับ CI ได้ง่าย เช่น การใช้งาน
Intervention Image ที่สามารถใช้เราจัดการกับรุปภาพได้ง่ายๆ
สะดวก และครอบคลุมการทำงานหลักๆ ที่สำคัญ สามารถทบทวนที่
แนวทาง การใช้งาน Intervention Image ปรับแต่งรูปภาพใน PHP ตอนที่ 1 http://niik.in/822
https://www.ninenik.com/content.php?arti_id=822 via @ninenik
อย่างไรก็ตาม ใน CI ก็มี Library ให้เราสามารถจัดการกับรูปภาพ ในฟังก์ชั่น และคำสั่งจำเป็นพื้นฐาน
ให้เราสามารถเรียกใช้งานได้เลย ไม่ต้องติดตั้งอะไรเพิ่ม เนื้อหาในบทความนี้ เราจะมาดูว่า ใน CI จะมีการ
จัดการกับรูปภาพด้วยคำสั่งอะไรบ้าง และเราสามารถจะนำมาประยุกต์ใช้งานได้อย่างไร
เราจะอธิบาย โดยจำลองการใช้งานร่วมกับบทความเกี่ยวกับการอัพโหลดโฟล์ใน CI ตามบทความด้านล่าง
การอัพโหลด และการจัดการ File ใน CodeIgniter 4 http://niik.in/1008
https://www.ninenik.com/content.php?arti_id=1008 via @ninenik
เตรียมส่วนของไฟล์ทดสอบ
ให้เราเตรียมส่วนของไฟล์ทดสอบตามรูปแบบดังนี้
app/Controllers/Helloworld.php
<?php namespace App\Controllers; use CodeIgniter\Controller; // เรียกใช้งาน Controller class class Helloworld extends Controller { public function index() { helper('form'); // ใช้งาน form helper ฟังก์ชั่น $data = [ 'title' => 'test image manipulation' ]; echo view('pages/myform', $data); } // เนื้อหาในบทความ http://niik.in/1008 public function addphoto(){ $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ echo $file->getClientName(); echo $file->getName(); echo $file->getExtension(); echo $file->getSize(); } } }
ส่วนของฟอร์มสำหรับอัพโหลดไฟล์
app/Views/pages/myform.php
<!doctype html> <html lang="th"> <head> <meta charset="utf-8"> <title><?= esc($title) ?></title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> </head> <body> <!-- ส่วนของข้อมูลฟอร์ม ที่เราจะเพิ่ม--> <?= form_open_multipart('helloworld/addphoto') ?> <input type="file" name="photo"> <button type="submit">Upload Photo</button> <?= form_close() ?> <!-- สร้างลิ้งค์สำหรับรีโหลดหน้าทดสอบ--> <?= anchor(current_url(),'Reload') ?> </body> </html>
ตัวอย่างไฟล์เริ่มต้นของเรา จะทำการอัพโหลดไฟล์ไปไว้โนโฟลเดอร์ public/uploads/product
เราจะจัดการไฟล์ที่อัพโหลดด้วยคำสั่งจัดการรูปภาพใน CI
การเรียกใช้งาน class จัดการรูปภาพ ใน CI
เราสามารถเรียกใช้งาน Image Manipulation Class หรือ class จัดการรูปภาพด้วยคำสังดังนี้
$image = \Config\Services::image(); // หรือ $image = service('image');
เราสามารถกำหนด parameter เพื่อกำหนด image library ที่จะใช้งาน ในรูปแบบดังนี้ได้
$image = \Config\Services::image('imagick'); // หรือ $image = service('image','imagick');
โดยค่า gd คือ GD/GD2 image library
โดยค่า imagick คือ ImageMagick library.
หากเรียกใช้งานโดยไม่กำหนด parameter ของ image library จะใช้ค่าที่กำหนดไว้ใน Images.php
app/Config/Images.php (บางส่วน)
/** * Default handler used if no other handler is specified. * * @var string */ public $defaultHandler = 'gd'; /** * The path to the image library. * Required for ImageMagick, GraphicsMagick, or NetPBM. * * @var string */ public $libraryPath = '/usr/local/bin/convert';
และหากกำหนดเป็น imagick เราจำเป็นจะต้องกำหนด path ของ library ด้วยเสมอ ในที่นี้เราจะไม่กำหนด
parameter จะใช้เป็น GD/GD2 image library สำหรับจัดการรูปภาพ
เมื่อเราได้ Instance ของ class มาไว้ในตัวแปร $image แล้ว เราก็สามารถเรียกใช้คำสั่งต่างๆ ได้ดังต่อไปนี้
$image->crop() ตัดเฉพาะบริเวณหรือ crop รูปตามจุดบริเวณ แล้วปรับขนาดตามกำหนด $image->convert() แปลงไฟล์เป็นชนิดอื่น เช่น jpg ไปเป็น png $image->fit() ตัดเฉพาะบริเวณหรือ crop รูปด้วยวิธีอัตโนมัติ แล้วปรับขนาดตามกำหนด $image->flatten() กำหนดสีพื้นหลังให้กับรูปภาพโดยเฉพาะภาพโปร่งใสอย่าง png $image->flip() กลับภาพแนวตั้งหรือแนวนอน $image->resize() ปรับขนาดความกว้าง / สูง ของรูปภาพ $image->rotate() หมุนรูปภาพที่ 90, 180 หรือ 270 องศา $image->text() แสดงข้อความในรูปภาพ
ในการจัดการรูปภาพ จะมี 2 คำสั่งหลักที่เราต้องเรียกใช้งานคือ withFile() และ save()
โดยคำสั่ง withFile() เป็นการระบุ path ของไฟล์ที่เราจะใช้งาน ส่วนคำสั่ง save() ใช้ระบุ path และชื่อไฟล์
ที่เราต้องการบันทึก รูปแบบการเรียกใช้งานเบื้องต้นจะเป็นดังนี้
$image->withFile() // path ไฟล์จะใช้งาน ->save(); // path และชื่อไฟล์ที่จะบันทึก
การเรียกใช้งาน instance กับคำสั่งต่างๆ จะใช้ในรูปแบบกำหนดต่อเนื่อง กรณีต้องการแยกทำแต่ละคำสั่ง
สามารถกำหนดได้ดังนี้
$image->withFile(); // คำสั่งอื่นๆ $image->save();
ใช้สำหรับกรณี ต้องการแทรกการทำงาน บางอย่างที่อาจต้องกำหนดภายในเงื่อนไขเฉพาะ
คำสั่ง withFile() ถ้าใช้กับไฟล์รูปที่เรารู้ตำแหน่งอยู่แล้วก็สามารถระบุตำแหน่งของไฟล์นั้นๆ ได้ หรือกรณี
ใช้กับรูปที่เพิ่งอัพโหลดไป เราสามารถใช้คำสั่งที่แสดงชื่อ และ path ของไฟล์ที่เพิ่งอัพโหลดได้ด้วยรูปแบบ
คำสั่งดังต่อไปนี้ได้
$file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$file->getName(); $image->withFile($file->getTempName().$file->getName()) ->save($thumbPath); }
ตัวอย่างข้างต้น เราอัพโหลดไฟล์ไปที่ 'public/uploads/product' หลังจากอัพโหลดแล้ว เราสามารถเรียก
ใช้งาน path ไฟล์ได้ผ่านคำสั่ง $file->getTempName().$file->getName() โดยต่อกันเป็น path ไฟล์ที่จะใช้
และกำหนดให้บันทึกไว้ในชื่อเดิมในโฟลเดอร์ 'public/uploads/product/thumbnail/'
คำสั่ง save() จะสามารถกำหนด parameter ที่สองเป็นค่าตัวเลขแสดงเปอร์เซ็นต์ของคุณภาพรูปที่จะบันทึก
โดยจะใช้ได้เฉพาะกับกรณีเป็นไฟล์ jpg หรือ JPEG เท่านั้น
$image->withFile('/path/to/image/mypic.jpg') // ส่วนแทรก คำสั่งจัดการรูปภาพที่ต้องการ ->save('/path/to/image/my_low_quality_pic.jpg', 10); // กำหนดคุณภาพรูป 10 %
ถ้าต้องการปรับเฉพาะคุณภาพของรูป และไม่ต้องการทำคำสั่งใดๆ กับรูป ให้เรากำหนดคำสั่ง withResource()
แทนเข้าไปประมาณนี้
app/Controllers/Helloworld.php (บางส่วน)
public function addphoto(){ $image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$file->getName(); $image->withFile($file->getTempName().$file->getName()) ->withResource() ->save($thumbPath, 90); } }
เราสามารถเรียกใช้คำสั่งที่เกี่ยวกับการจัดการรูป ต่อเนื่องกัน โดยที่จะไม่มีการปรับหรือแก้ไขไฟลฺ์ต้นฉบับ ดูตัวอย่าง
การเรียกใช้คำสั่งต่อเนื่องด้านล่างประกอบ
$image->withFile('/path/to/image/mypic.jpg') ->reorient() ->rotate(90) ->crop(100, 100, 0, 0) ->save('/path/to/image/mypic_thumb.jpg');
คำสั่งข้างต้น จะทำการสร้างรูปใหม่จากรูปต้นฉบับโดยใช้ GD2 image library จากนั้นนำไปจัดการหรือเข้าสูการใช้
คำสั่งต่างๆที่ต้องการ เช่นการปรับหมุนรูปที่ 90 องศา แล้วต่อด้วยทำการ crop รูปและปรับขนาดให้อยู่ที่ 100x100 px
แล้วบันทึกไปยัง path ไฟล์ใหม่
ในกรณีที่เราต้องการจัดการกับ error หากไม่ผานการดำเนินการ เมื่อใช้คำสั่งต่างๆ ผ่าน instance สามารถปรับ
ประยุกต์ใช้งานได้ประมาณนี้
// สมมติไม่มี โฟลเดอร์ที่กำหนด thumbnailxxx $thumbPath = ROOTPATH.'public/uploads/product/thumbnailxxx/'.$file->getName(); try{ $image->withFile($file->getTempName().$file->getName()) ->withResource() ->save($thumbPath, 90); }catch(CodeIgniter\Images\ImageException $e){ echo $e->getMessage(); }
เราสามารถแสดงข้อมูลของไฟล์รูปต้นฉบับ เช่น ความกว้าง ความสูง ชนิดของไฟล์รูป เพื่อนำไปใช้งานบางอย่างได้
$info = $image->withFile($file->getTempName().$file->getName()) ->getFile() ->getProperties(true);
จะได้ค่าข้อมูลของตัวแปร $info เป็น array รูปแบบดังนี้
Array ( [width] => 205 [height] => 150 [image_type] => 2 [size_str] => width="205" height="150" [mime_type] => image/jpeg )
สามารถใช้ค่า เช่น $info['width'] หรือ $info['height'] ไปจัดการ หรือทำงานบางอย่างได้
คำสั่ง convert()
ใช้สำหรับแปลงชนิดของไฟล์รูปภาพ ไปเป็นรูปแบบที่ต้องการ เช่น เปลี่ยนจาก jpg เป็น png เปลี่ยนจาก gif เป็น
jpg เป็นต้น การกำหนดว่า จะแปลงเป็นไฟล์นามสกุลอะไรนั้น จะดูที่ชื่อของนามสกุลไฟล์ที่บันทึก เช่น ถ้าบันทึกเป็น
ไฟล์ mypic.png ก็แสดงว่าเราต้องการแปลงเป็นไฟล์ png
มีรูปแบบการใช้งาน และรองรับการกำหนด parameter ดังนี้
convert(int $imageType)
Parameters:
$imageType (int) – กำหนดชนิดของไฟล์รูปที่จะใช้แปลง สามารถใช้ค่า คงที่ใน PHP ได้ ตัวอย่างค่าที่มักใช้บ่อย
IMAGETYPE_GIF | IMAGETYPE_JPEG | IMAGETYPE_PNG หรือดูเพิ่มเติม image_type_to_mime_type
ตัวอย่างการใช้งาน
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ // สร้างชื่อไฟล์ใหม่ ต้องการใช้เเป็นชื่อเดิม และเปลี่ยนเป็น png $newFilename = implode(".", [pathinfo($file->getName())['filename'],"png"]); // ต้องการชื่อเดิม ต่อด้วย _thumb และเปลี่ยนเป็น png // $newFilename = implode(".", [pathinfo($file->getName())['filename']."_thumb","png"]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->convert(IMAGETYPE_JPEG) // ต้องการแปลงจากไฟล์ JPEG ->save($thumbPath); }
ในตัวอย่าง เราแสดงการประยุกต๋ใช้งาน จะเห็นว่าส่วนของการเปลี่ยนชนิดของไฟล์มีไม่กี่บรรทัด การประยุกต์ข้างต้น
เราทำการแยกเอาเฉพาะชื่อของไฟล์ โดยใช้ฟังก์ชั่น pathinfo() ของ PHP จากนั้นเอาเฉพาะชื่อไฟล์ โดยกำหนด
key ของข้อมูล เป็น
pathinfo($file->getName())['filename'] // ได้เฉพาะชื่อของไฟล์
ข้างต้นเรากำหนดชื่อของไฟล์ และนามสกุลไว้ใน array แล้วใช้คำสั่ง implode() ต่อค่าทั้งสองด้วย ( . ) เราก็จะได้
ชื่อไฟล์ตามต้องการ กรณีใช้ชื่อเดิม และเปลี่ยนเฉพาะนามสกุลไฟล์
นอกจากนั้นในตัวอย่าง ยังมีรูปแบบการกำหนดชื่อเติม และต่อด้วยคำว่า _thumb สำหรับไฟล์ใหม่ให้ด้วย
pathinfo($file->getName())['filename']."_thumb" // ได้เฉพาะชื่อ และต่อด้วย _thumb
คำสั่ง convert() ค่า parameter ที่กำหนด จะหมายถึงชนิดของไฟล์ที่เราจะใช้แปลง ไม่ได้หมายถึงไฟล์ที่จะแปลง
ดังนั้น ถ้าเราอัพโหลดรุปหรือใช้รูปที่ไม่ใช่ JPEG ก็จะเกิด error ขึ้น เพราะเราต้องใช้เป็น JPEG ตามที่ระบุเท่านั้น
คำสั่ง flip()
ใช้สำหรับกลับรูปภาพ ทั้งแบบกลับภาพบน-ล่าง หรือแบบกลับภาพซ้าย-ขวา
มีรูปแบบการใช้งาน และรองรับการกำหนด parameter ดังนี้
flip(string $dir)
Parameters:
$dir (string) – กำหนดข้อความรูปแบบ 'vertical' กลับภาพบน-ล่าง หรือ 'horizontal' กลับภาพซ้าย-ขวา
ตัวอย่างการใช้งาน
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumb", $file->getExtension() ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->flip('vertical') // vertical | horizontal ->save($thumbPath); }
คำสั่ง rotate()
ใช้สำหรับหมุนรูปภาพไปที่ 90, 180 หรือ 270 องศา หากกำหนดเป็นค่าอื่น ที่ไม่ใช่สามค่าข้างต้น จะเกิด error
มีรูปแบบการใช้งาน และรองรับการกำหนด parameter ดังนี้
rotate(float $angle)
Parameters:
$angle (float) – กำหนดค่าองศาการหมุนที่ 90, 180 หรือ 270 องศา
ตัวอย่างการใช้งาน
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumb", $file->getExtension() ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->rotate(90) // 90 | 180 | 270 ->save($thumbPath); }
ในบางกรณี เช่น การใช้มือถือถ่ายรูปแล้วมีการกำหนดการตั้งค่าแนวตั้งหรือแนวนอนไว้ในข้อมูลรูป หรือที่
อยู่ในค่า EXIF information ในรุปภาพ เราสามารถใช้คำสั่ง reorient() เพื่อหมุนรูปให้เป็นไปตามค่าของรูปนั้นๆ
โดยสามารถกำหนดค่า parameter เป็นโหมดให้ไม่ต้องแสดง error หากไม่มีข้อมูล EXIF ดังนี้ได้
$image->withFile($file->getTempName().$file->getName()) ->reorient(true) // หมุนรูปจากค่า EXIF (ถ้ามี) ก่อน ->rotate(90) // 90 | 180 | 270 ->save($thumbPath);
คำสั่ง reorient(true) จะทำการหมุนรูปตามค่าข้อมูล EXIF (ถ้ามี) ให้เป็นค่าที่ถูกต้องก่อน แล้วค่อยให้คำสั่ง
rotate() เพื่อหมุนรูปตามค่าที่ต้องการอีกครั้ง
คำสั่ง flatten()
ใช้สำหรับกำหนดสีพื้นหลังให้กับรูปภาพโดยเฉพาะภาพโปร่งใสของไฟล์ภาพ PNG โดยเปลี่ยนจาก RGBA pixel
ไปเป็น RGB pixel หรือเปลี่ยนจากไฟล์ PNG เป็น JPEG
มีรูปแบบการใช้งาน และรองรับการกำหนด parameter ดังนี้
flatten(int $red = 255, int $green = 255, int $blue = 255)
Parameters:
$red (int) – ค่าตัวเลขกำหนดสีแดง (0 - 255)
$green (int) – ค่าตัวเลขกำหนดสีเขียว (0 - 255)
$blue (int) – ค่าตัวเลขกำหนดสีน้ำเงิน (0 - 255)
หากไม่กำหนดค่าใดๆ จะใช้ค่าเริ่มต้น เป็นสีขาว หรือมีค่า RGB เท่ากับ 255, 255, 255 ตามลำดับ
ตัวอย่างการใช้งาน
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumbx", "jpg" ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->flatten(255,255,0) ->save($thumbPath); }
คำสั่งนี้ หลังจากทดสอบใช้งาน เหมือนจะมี bug อยู่เพราะสีพื้นหลังยังไม่เปลี่ยนไปตามค่าที่กำหนด จะเป็นได้
เฉพาะสีขาวเท่านั้น
คำสั่ง fit()
ใช้สำหรับตัดภาพในสัดส่วนที่เหมาะสมให้อัตโนมัติ แล้วปรับให้มีขนาดตามที่ระบุ สามารถกำหนดจุดหรือตำแหน่ง
ที่ใช้สำหรับเป็นตัวกำหนดในการหากึ่งกลางของรูปภาพ ก่อนทำการตัดภาพ เช่น center เป็นการบอกตำแหน่งของรูป
ที่จะตัดให้ใช้จุดกึ่งกลางของรูปเดิม แล้วกำหนดสัดส่วนการตัดให้อัตโนมัติ เป็นต้น ดูรูปประกอบ
กระบวนการทำงานของคำสั่งนี้คือ
- คำนวณหาตำแหน่งและสัดส่วนที่เหมาะสมของพื้นรูปต้นฉบับที่จะตัด
- ตัดรูปต้นฉบับในสัดส่วนที่เหมาะสม
- ปรับขนาดตามค่าที่กำหนด
มีรูปแบบการใช้งาน และรองรับการกำหนด parameter ดังนี้
fit(int $width, int $height = null, string $position = 'center')
Parameters:
$width (int) – กำหนดความกว้าง pixel
$height (int) – กำหนดความสูง pixel
$position (string) – ตำแหน่งที่ใช้คำนวณหาสัดส่วน ‘top-left’, ‘top’, ‘top-right’, ‘left’, ‘center’,
‘right’, ‘bottom-left’, ‘bottom’, ‘bottom-right’.
ตัวอย่างการใช้งาน
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumb", $file->getExtension() ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->fit(150,150,'center') ->save($thumbPath); }
คำสั่งข้างต้น ทำการสร้างรูป thumbnail ที่มีขนาด 150x150 ใช้ตำแหน่งตรงกลางหาสัดส่วนที่เหมาะสมอัตโนมัติ
คำสั่ง crop()
ใช้สำหรับตัดเฉพาะบางส่วนของรูป โดยจะเน้นการคงสัดส่วนเดิมของภาพต้นฉบับไว้ เข้าใจอย่างง่ายคือ
เหมือนตัดรูปเอาเฉพาะบางส่วนของต้นฉบับมา
มีรูปแบบการใช้งาน และรองรับการกำหนด parameter ดังนี้
crop(int $width = null, int $height = null, int $x = null, int $y = null, bool $maintainRatio = false, string $masterDim = 'auto')
Parameters:
$width (int) – กำหนดความกว้าง pixel
$height (int) – กำหนดความสูง pixel
$x (int) – กำหนดพิกัด x ตำแหน่งเริ่มต้น
$y (int) – กำหนดพิกัด y ตำแหน่งเริ่มต้น
$maintainRatio (bool) – กำหนดการคงสัดส่วนตามต้นฉบับหรือไม่ ค่าเริ่มต้นเป็น false
$masterDim (string) – กำหนดสำหรับกรณี $maintainRatio เป็น true แล้วไม่ต้องการให้แก้ไขสัดส่วน
ในส่วนไหน สมมติเช่น ถ้าต้องการให้ความกว้างเป็นค่าตามกำหนดใน $width เราก็กำหนด
ค่าเป็น ‘width’ ดังนั้นเพื่อให้ได้สัดส่วน ความสูงก็จะถูกปรับขนาดให้ได้สัดส่วน ค่าเริ่มต้นเป็น
'auto' สามารถกำหนดเป็น 'width' หรือ 'height' หรือ 'auto'
จะขออธิบายแต่ละกรณีการใช้งาน ดังนี้
สมมติขนาดรูปต้นฉบับเราเป็น 300x340
กำหนดขนาดที่ตัด ไม่เกินขนาดของต้นฉบับ
crop(100,100,50,50)
คำสั่งข้างต้น เราจะได้รูปที่อยู่พื้นที่ของรูปต้นฉบับ มีขนาดตายตัวเป็น 100x100
การที่รูปอยู่ในพื้นที่ของรูปต้นฉบับคือ ตำแหน่งรูปเริ่มที่ 50 + ความกว้าง 100 ก็จบส่วนของความกว้างที่ 150
และรูปมีความกว้างเท่ากับ 300 จึงไม่เกินขนาดของต้นฉบับ
กำหนดขนาดที่ตัด มากกว่าขนาดรูปต้นฉบับ
crop(350,300,0,0) crop(150,300,200,0)
ดูรุปประกอบ
ถ้ากำหนดความกว้างหรือสูง เกินขนาดของรูป พื้นที่ที่เกินมาจะเป็นสีดำ ตัวอย่าง crop(350,300,0,0)
เนื่องจากรูปมีขนาด 300 คำสั่งแรก ความกว้างเกินขนาดของรูป พื้นที่ที่เกินจะเป็นสีดำ เช่นเดียวกับกรณีที่สอง
ถึงเราจะกำหนดขนาดความกว้างน้อย 300 คือกำหนดเท่ากับ 150 แต่เราไปเริ่มตำแหน่งรูปที่ 200 แสดงว่าจุดสิ้นสุด
ของรูปจะอยู่ที่ 150 + 200 เท่ากับ 350 ซึ่งเกินตำแหน่งของรูปต้นฉบับ พื้นที่ส่วนเกินจะเป็นสีดำ
การใช้งานคำสั่งโดยไม่ได้กำหนดค่า $maintainRatio เป็น true เราจะได้รูปที่ขนาดความกว้างและความสูง
ตามค่าที่กำหนด
กำหนดการคงอัตรส่วนรูปต้นฉบับ
crop(100,100,50,50,true)
กรณีนี้ ขนาดของรูปจะไม่เป็น 100x100 หรือไม่เป็นตามค่าที่กำหนดเสมอไป ขึ้นกับสัดส่วนของรูปต้นฉบับ
ซึ่งถ้าสัดส่วนต้นฉบับเป็น 1:1 เช่น 300x300 เราก็จะได้รูป 100x100 เพราะสัดส่วนจะได้ 1:1 เหมือนกัน แต่เนื่องจาก
รูปเราเป็น 300:340 หรือ 15:17 รูปที่ได้ จะถูกำหนดการลดอัตราส่วนอัตโนมัติ จะได้รูปที่ขนาด 89x100 หรือ 89:100
ถ้าเราหารค่าเพื่อดูอัตราส่วนโดยประมาณ 300/340 = 0.88 และ 89/100 = 0.89 จะเห็นว่าเมื่อกำหนดการคง
อัตราส่วนของรูปเป็น true ขนาดของรูปจะปรับลดอัตโนมัติให้ได้สัดส่วน ที่ใกล้เคียงหรือเท่ากับต้นฉบับ
ในการคงอัตราส่วน เราสามารถฟิกส่วนที่ต้องการให้ค่าเป็นไปตามที่กำหนด แล้วให้ส่วนอื่น ปรับเพิ่มหรือลดให้ได้สัดส่วน
แทนได้ ตัวอย่างเช่น
crop(100,100,50,50,true,'width')
เรากำหนดค่า $masterDim เป็น 'width' นั่นคือให้ความกว้างมีขนาดตามที่กำหนด ก็คือ 100 ดังนั้นเพื่อให้ได้สัดส่วน
100/x เมื่อ x คือความสูง จะต้องเป็นค่าที่ทำให้ได้สัดส่วน คำสั่งข้างต้น จะได้รูปที่ขนาด 100x114 โดยที่ 100/114 = 0.877
เป็นสัดส่วนที่ใกล้เคียงกับต้นฉบับ
ตัวอย่างการใช้งาน
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumb", $file->getExtension() ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->crop(100,100,50,50) ->save($thumbPath); }
ถ้าเราต้องการตัดรูป โดยอิงตำแหน่งตรงกลางจากรูปต้นฉบับ เราสามารถคำนวณหาตำแหน่ง x,y สำหรับค่า
เริ่มต้นด้วยรูปแบบการใช้งานดังนี้
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumb", $file->getExtension() ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $info = $image->withFile($file->getTempName().$file->getName()) ->getFile() ->getProperties(true); $xOffset = ($info['width'] / 2) - 50; $yOffset = ($info['height'] / 2) - 50; $image->withFile($file->getTempName().$file->getName()) ->crop(100,100,$xOffset,$yOffset) ->save($thumbPath); }
คำสั่ง resize()
ใช้สำหรับปรับขนาดของรูปภาพตามต้องการ
มีรูปแบบการใช้งาน และรองรับการกำหนด parameter ดังนี้
resize(int $width, int $height, bool $maintainRatio = false, string $masterDim = 'auto')
Parameters:
$width (int) – กำหนดความกว้าง pixel
$height (int) – กำหนดความสูง pixel
$maintainRatio (bool) – กำหนดการคงสัดส่วนตามต้นฉบับหรือไม่ ค่าเริ่มต้นเป็น false
$masterDim (string) – กำหนดสำหรับกรณี $maintainRatio เป็น true แล้วไม่ต้องการให้แก้ไขสัดส่วน
ในส่วนไหน สมมติเช่น ถ้าต้องการให้ความกว้างเป็นค่าตามกำหนดใน $width เราก็กำหนด
ค่าเป็น ‘width’ ดังนั้นเพื่อให้ได้สัดส่วน ความสูงก็จะถูกปรับขนาดให้ได้สัดส่วน สามารถ
กำหนดเป็น 'width' หรือ 'height'
แนวทางการกำหนด และใช้งาน $maintainRatio กับ $masterDim จะคล้ายๆ การใช้งานในคำสัง crop()
จะขออธิบายแต่ละกรณีการใช้งาน ดังนี้
สมมติขนาดรูปต้นฉบับเราเป็น 300x340
กำหนดความกว้างความสูงตามต้องการ
resize(100,100) resize(400,400)
รูปจะถูกปรับเพิ่ม ลด ขนาดตามค่าที่กำหนด รูปที่ได้จะไม่เป็นสัดส่วนเหมือนต้นฉบับ อาจดูผิดเพื้ยน ยึดหด ตาม
ความกว้างหรือความสูงที่เปลี่ยนแปลง
กำหนดความกว้างความสูงขึ้นกับสัดส่วนต้นฉบับ
resize(100,100,true) resize(400,400,true)
รูปจะถูกปรับเพิ่ม ลด ขนาดแต่อาจจะไม่ได้ตามค่าที่กำหนด เพราะจะต้องได้สัดส่วนตามต้นฉบับ ค่าจะยึดว่าจะให้
ความกว้าง หรือความสูงเป็นตามที่กำหนด แล้วให้ค่าที่เหลือปรับตามสัดส่วน กรณีนี้ ถ้าขนาด 100x100 ก็จะเหลือเป็น
98x100 แทน เพื่อให้รูปได้สัดส่วนตามรูปต้นฉบับ เหมือนทีอธิบายไปแล้ว ในคำสั่ง crop()
กำหนดความกว้างความสูงขึ้นกับสัดส่วนต้นฉบับ แบบระบุค่าที่ต้องการฟิก
resize(100,100,true,'width') resize(400,400,true,'height')
รูปจะถูกปรับเพิ่ม ลด ขนาดจะได้ตามค่าที่กำหนดเฉพาะส่วนที่กำหนดใน $masterDim เท่านั้น ส่วนค่าทีไม่ได้กำหนด
ก็จะปรับขนาดให้ได้สัดส่วน เช่น ที่รูป 400x400 จะได้ความสูงที่ 400 แต่ความกว้างจะถูกปรับให้ได้สัดส่วนที่ขนาด 353px
ตัวอย่างการใช้งาน
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumb", $file->getExtension() ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->resize(400,400) ->save($thumbPath); }
คำสั่งข้างต้น เราจะได้รูปภาพที่ขนาด 400x400
คำสั่ง text()
ใช้สำหรับใส่ข้อความบนรูปภาพ หรือการใส่ลายน้ำในรูปภาพ สามารถใช้ไฟล์ font นามสกุล TTF (TrueType font) ได้
โดยต้องระบุ path ไปยังไฟล์ที่จะใช้งานด้วย หากไม่เจอไฟล์นั้น จะใช้ font ของระบบแทน
มีรูปแบบการใช้งาน และรองรับการกำหนด parameter ดังนี้
text(string $text, array $options = [])
Parameters:
$text (string) – ข้อความที่ต้องการแสดง
$options (array) – กำหนดค่าต่างๆ ของการใช้งาน font
color - สีข้อความ (hex number) เช่น #ff0000
opacity - ค่าความโปร่งใส เลขทศนิยมระหว่าง 0 - 1 เช่น 0.5
withShadow - ค่า Boolean แสดงเงาหรือไม่
shadowColor - ค่าสีของเงา ถ้ากำหนดให้แสดงเงา (hex number)
shadowOffset - จำนวน pixel เงา ที่แสดงเยี้ยงจากข้อความ ทั้งแนวตั้งและแนวนอน
hAlign - ตำแหน่งข้อความในแนวนอน left, center, right
vAlign - ตำแหน่งข้อความในแนวตั้ง top, middle, bottom
hOffset - จำนวน pixel ที่ต้องการเยื้องในแนวนอน
vOffset - จำนวน pixel ที่ต้องการเยื้องในแนวตั้ง
fontPath - path ของไฟล์ font (TTF) ไฟล์ บน server ที่จะใช้งาน หากไม่กำหนดจะใช้ของระบบ
fontSize - ขนาดของ font ถ้าใช้ของระบบ และใช้งาน GD จะกำหนดค่าที่ 1-5 กรณีอื่น กำหนดค่าตามต้องการ
ตัวอย่างการใช้งาน
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumb", $file->getExtension() ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->text('Copyright 2017 My Photo Co', [ 'color' => '#FFFFFF', 'opacity' => 0.5, 'withShadow' => true, 'hAlign' => 'center', 'vAlign' => 'bottom', 'fontSize' => 5 ]) ->save($thumbPath); }
ผลลัพธ์ที่ได้
ตัวอย่างการใช้งาน font โดยเราเก็บไฟล์ไว้ที่ public/fonts/Chonburi/
$image = service('image'); $file = $this->request->getFile('photo'); $destPath = ROOTPATH.'public/uploads/product'; if ($file->isValid() && !$file->hasMoved() && $file->move($destPath)){ $newFilename = implode(".", [ pathinfo($file->getName())['filename']."_thumb", $file->getExtension() ]); $thumbPath = ROOTPATH.'public/uploads/product/thumbnail/'.$newFilename; $image->withFile($file->getTempName().$file->getName()) ->text('ภาษาไทย', [ 'color' => '#FFFFFF', 'opacity' => 0.5, 'withShadow' => true, 'hAlign' => 'center', 'vAlign' => 'bottom', 'fontPath' => ROOTPATH.'public/fonts/Chonburi/Chonburi-Regular.ttf', 'fontSize' => 16 ]) ->save($thumbPath); }
ตัวอย่างผลลัพธ์ที่ได้
ถือได้ว่าเป็นอีกความสามารถที่เรานำมาใช้งานได้โดยง่าย และปรับประยุกต์เพิ่มเติมได้ตามต้องการ โดยเฉพาะ การใช้
สร้างรูป thumbnail หรือการใช้สำหรับปรับรูปให้มีขนาดตามอุปกรณ์ที่ใช้งาน เช่น รูปที่มีขนาดใหญ่ มีความละเอียดสูง
เราก็อาจจะใช้แสดงในอุปกรณ์พวก desktop เป็นต้น
หวังว่าแนวทางนี้จะเป็นประโยชน์สำหรับนำไปปรับใช้งานต่อไป