11/08/2018, 23:37

Giới thiệu thư viện ImageMagick trong ngôn ngữ PHP

Giới thiệu về ImageMagick ImageMagick là một thư viện được phát triển bao gồm các công cụ để thực hiện các thao tác với file ảnh ở rất nhiều định dạng bao gồm PNG, JPG, JPEG, GIF, PDF, TIFF, SVG,... ImageMagick có thể giúp bạn thực hiện các thao tác từ đơn giản như: dịch chuyển, thay đổi ...

  1. Giới thiệu về ImageMagick

       ImageMagick là một thư viện được phát triển bao gồm các công cụ để thực hiện các thao tác với file ảnh ở rất nhiều định dạng bao gồm PNG, JPG, JPEG, GIF, PDF, TIFF, SVG,... ImageMagick có thể giúp bạn thực hiện các thao tác từ đơn giản như: dịch chuyển, thay đổi kích thước, xoay, kéo xiên, thu phóng hỉnh, điều chỉnh màu sắc, vẽ vẵn bản, hình học... cho đến thêm các hiệu hứng phức tạp như các bộ lọc gotham, lomo, kelvin, toaster (bộ lọc phức tạp nhất)và nashville (bộ lọc phổ biến nhất).

       Các chức năng của ImageMagick có thể được sử dụng thông qua giao diện dòng lệnh của hệ điều hành hoặc giao diện lập trình ứng dụng API cho nhiều ngôn ngữ lập trình khác nhau bao gồm MagickCore (C), MagickWand (C), Magick + + (C + +), JMagick (Java), MagickNet (. NET), MagickWand (PHP), IMagick (PHP), RMagick (Ruby), PythonMagick (Python), PascalMagick (Pascal), G2F (Ada), ChMagick (Ch), ImageMagickObject (COM +), L-Magick (Lisp), NMagick (Neko / haXe), PerlMagick (Perl), hoặc TclMagick (Tcl / TK)

       ImageMagick là thư viện phần mềm tự do với một giấy phép riêng, tương đương với GPL. Tên gọi ImageMagick ghép từ Image (hình ảnh) và Magick (đọc giống như Magic nghĩa là phép thuật).

       Một vài ví dụ về những gì ImageMagick có thể làm:
- Vẽ: thêm hình hoặc văn bản vào hình ảnh.
- Chuyển đổi: thay đổi kích cỡ, xoay, cắt, lật hoặc cắt một hình ảnh.
- Trang trí: thêm viền, khung cho ảnh.
- Chuyển đổi định dạng : chuyển đổi một hình ảnh từ định dạng này sang định dạng khác.
- Hoạt hình: tạo ra một hình ảnh động GIF từ một nhóm các hình ảnh tĩnh.
- Văn bản: chèn mô tả hoặc văn bản nghệ thuật trong ảnh.
- Virtual pixel : thuận tiện tiếp cận với các điểm ảnh bên ngoài khu vực hình ảnh.
- Hình ảnh nhận dạng: mô tả các định dạng và thuộc tính của hình ảnh.
- Composite: chồng lên một hình ảnh khác.
- Montage: để hình ảnh và hình thu nhỏ cạnh nhau trên một khung hình ảnh.
- Hiệu ứng đặc biệt: làm mờ, làm sắc nét, hoặc tô màu một hình ảnh.
- Discrete Fourier transform : thực hiện chuyển tiếp và đảo nghịch DFT.
- Motion picture support : đọc và viết các định dạng hình ảnh phổ biến được sử dụng trong công việc phim ảnh kỹ thuật số.
- High dynamic-range images: chính xác mức cường độ tìm thấy trong những cảnh thực tế khác nhau.
- Hổ trợ hình ảnh lớn : đọc, xử lý, hoặc viết tera-pixel.....
- Image calculator: áp dụng một biểu thức toán học với một kênh hình ảnh.
và còn nhiều chức năng khác nữa.

2. Thực hiện một số bộ lọc trong PHP với ImageMagick

       Dưới đây là một số ví dụ về việc sử dụng các hàm của thư viện ImageMagick trong ngôn ngữ PHP để tạo ra một số bộ lọc hình ảnh, nhằm mang lại các hiệu ứng làm bức ảnh của bạn trở nên mới lạ và thú vị hơn.

       Đầu tiên hãy tạo class Instagraph có nội dung như sau:

/**
 * @package    Instagraph
 * @author     Webarto <dejan.marjanovic@gmail.com>
 * @copyright  NetTuts+
 * @license    http://creativecommons.org/licenses/by-nc/3.0/ CC BY-NC
 */
class Instagraph {
    public $_image = NULL;
    public $_output = NULL;
    public $_prefix = 'IMG';
    private $_awidth = NULL;
    private $_height = NULL;
    private $_tmp = NULL;

    public static function factory ($image, $output) {
        return new Instagraph($image, $output);
    }

    public function __construct ($image, $output) {
        if (file_exists($image)) {
            $this->_image = $image;
            list($this->_awidth, $this->_height) = getimagesize($image);
            $this->_output = $output;
        } else {
            throw new Exception('File not found. Aborting.');
        }
    }

    public function tempfile () {
        # copy original file and assign temporary name
        $this->_tmp = $this->_prefix.rand();
        copy($this->_image, $this->_tmp);
    }

    public function output () {
        # rename working temporary file to output filename
        rename($this->_tmp, $this->_output);
    }

    public function execute ($command) {
        # remove newlines and convert single quotes to double to prevent errors
        $command = str_replace(array("
", "'"), array(', '"'), $command);
        $command = escapeshellcmd($command);
        # execute convert program
        exec($command);
    }

    /** ACTIONS */

    public function colortone ($input, $color, $level, $type=0) {
        $args[0] = $level;
        $args[1] = 100 - $level;
        $negate = $type == 0? '-negate': ';

        $this->execute("convert
        {$input}
        ( -clone 0 -fill '$color' -colorize 100% )
        ( -clone 0 -colorspace gray $negate )
        -compose blend -define compose:args=$args[0],$args[1] -composite
        {$input}");
    }

    public function border ($input, $color='black', $awidth=20) {
        $this->execute("convert $input -bordercolor $color -border {$awidth}x{$awidth} $input");
    }

    public function frame ($input, $frame) {
        $this->execute("convert $input ( '$frame' -resize {$this->_awidth}x{$this->_height}! -unsharp 1.5×1.0+1.5+0.02 ) -flatten $input");
    }

    public function vignette ($input, $color_1='none', $color_2='black', $crop_factor=1.5) {
        $crop_x = floor($this->_awidth * $crop_factor);
        $crop_y = floor($this->_height * $crop_factor);

        $this->execute("convert
        ( {$input} )
        ( -size {$crop_x}x{$crop_y}
        radial-gradient:$color_1-$color_2
        -gravity center -crop {$this->_awidth}x{$this->_height}+0+0 +repage )
        -compose multiply -flatten
        {$input}");
    }
    /** RESERVED FOR FILTER METHODS */
}
- Bộ lọc Gotham
    public function gotham () {
            $this->tempfile();
            $this->execute("convert $this->_tmp -modulate 120,10,100 -fill '#222b6d' -colorize 20 -gamma 0.5 -contrast -contrast $this->_tmp");
            $this->output();
    }
Bộ lọc này sẽ tạo ra một bức ảnh với 2 màu đen trắng và tông màu hơi xanh. Đầu tiên cần tăng độ sáng một chút, khử bão hòa, chuyển ảnh về màu tím đậm, giảm gamma và thêm độ tương phản 2 lần.
- Bộ lọc Toaster
    public function toaster() {
            $this->tempfile();
            $this->colortone($this->_tmp, '#330000', 100, 0);
            $this->execute("convert $this->_tmp -modulate 150,80,100 -gamma 1.2 -contrast -contrast $this->_tmp");
            $this->vignette($this->_tmp, 'none', 'LavenderBlush3');
            $this->vignette($this->_tmp, '#ff9966', 'none');
            $this->output();
    }
Bộ lọc này làm cho bức ảnh có màu cam ở giữa và nhạt dần ra xung quanh. Thứ tự thực hiện: thay màu đen bằng màu đỏ tối, tăng sáng, khử bão hoà, thêm độ tương phản, thêm độ tương phản, tăng gamma, thêm độ tương phản 2 lần. Cuối cùng thêm một số chi tiết màu xám ( giảm bão hoà 1 chút ), đảo màu ghi thành màu cam.
  1. Convert từ file PDF sang ảnh

       Ngày nay việc chia sẻ tài liệu, kiến thức trên internet được thực hiện rất thường xuyên. Các trang web chia sẻ tài liệu ngày một nhiều giúp cho việc chia sẻ kiến thức cho mọi người được thực hiện trở nên dễ dàng. Và một định dạng tài liệu được mọi người ưa thích và sử dụng nhiều là PDF.

       Tuy nhiên đôi khi người dùng xuất hiện nhu cầu chia sẻ file PDF lên internet nhưng muốn người xem không thể copy, edit được nội dung bên trong nó để tránh tình trạng vi phạm và ăn cắp bản quyền một cách tràn lan như thực trạng hiện nay. Để giải quyết nhu cầu này thì có một số cách như convert từ định dạng PDF sang định dạng flash (ví dụ như SWF) và dùng trình chơi flash để show nội dung, hoặc một cách đơn giản hơn là convert sang file ảnh rồi hiển thị cho người xem. Khi đó người xem chỉ có thể nhìn thấy nội dung file PDF mà không thể download file gốc về. Và họ cũng chỉ có thể download về các file sau khi đã được convert nên việc copy hay edit nội dung là không thể thực hiện. Với thư viện Imagick thì việc convert từ file PDF sang file ảnh được thực hiện một cách rất đơn giản.

       Đoạn code PHP sau thực hiện việc convert một file PDF thành nhiều file ảnh định dạng JPG.

$path_input = dirname(__FILE__) . "/../webroot/files/images/";
$file_name = 'test.pdf';
$solutionX = 115;
$solutionY = 115;
$compression = 99;
$file_input = $path_input . $file_name;
$imagick = new Imagick($file_input);
$total_page = $imagick->getNumberImages();
for($i=0; $i<$total_page; $i++) {
        $file_out_name = 'image' . $i . '.jpg';
        $file_output = $path_input . $file_out_name;
        if (!file_exists($file_output)) {
            $imagick->setResolution($solutionX, $solutionY);
            $imagick->readImage($file_input . '[' . $i . ']');
            $imagick->setImageCompressionQuality($compression);
            $imagick->writeImage($file_output);
        }
}

       Trong ví dụ trên, đầu tiên cần lấy số trang của file PDF rồi thực hiện convert từng trang sang định dạng JPG. Trong quá trình convert có thể lựa chọn các thông số độ phân giải theo chiều ngang, độ phân giải theo chiều dọc của ảnh output qua lệnh
$imagick->setResolution($solutionX, $solutionY);
và độ nén của ảnh qua lệnh
$imagick->setImageCompressionQuality($compression);
Giá trị $compression càng nhỏ thì chất lượng ảnh càng rõ, tuy nhiên dung lượng cũng về thế mà tăng lên. Do đó bạn cần lựa chọn giữa chất lượng ảnh và chi phí lưu trữ.

0