+1

Cấu hình Nginx để resize/crop image với module ngx_http_image_filter_module

Đặt bối cảnh chúng ta có một trang thương mại điện tử với rất nhiều sản phẩm, mỗi sản phẩm lại có nhiều hình ảnh giới thiệu với kích thước khá lớn. Nhưng ở trang list sản phẩm, chúng ta lại chỉ cần hiển thị các hình ảnh này ở kích thước thumbnail. Khi người dùng vào xem chi tiết sản phẩm chúng ta mới cần hiển thị hình ảnh kích thước đầy đủ. Vậy chúng ta có thể xử lý như thế nào để tăng tốc độ tải trang list sản phẩm qua đó tăng trải nghiệm người dùng? Trước đây tôi từng có ý định với mỗi ảnh đầy đủ của product được upload thì sẽ sử dụng imagick để generate ra 1 ảnh thumbnail và sử dụng nó cho trang list. Tuy nhiên sau khi tìm hiểu thì tôi thấy có 1 cách đơn giản hơn rất nhiều. Đó là sử dụng module ngx_http_image_filter_module của nginx. Cụ thể như thế nào chúng ta cùng tìm hiểu trong bài viết này.

Cài đặt

Trước tiên hãy cài đặt nginx và ngx_http_image_filter_module trên OS của bạn. Với centos:

yum install nginx -y
yum install nginx-mod-http-image-filter.x86_64 -y

Nếu bạn không tìm thấy module bạn có thể dùng lệnh dưới đây để tìm kiếm

yum search nginx | grep nginx-mod-http

Với ubuntu:

curl -O http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
sudo bash -c 'echo "deb http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx
deb-src http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx-stable.list'
sudo apt-get update
sudo apt-get install -y nginx nginx-module-image-filter

Sau khi cài đặt thư viện xong ta cần thêm nội dung sau vào file config của nginx ở đường dẫn /etc/nginx/nginx.conf để có thể sử dụng được

load_module modules/ngx_http_image_filter_module.so;

Cấu hình bộ lọc hình ảnh

Một cấu hình đơn giản cho việc chuyển đổi một định dạng jpg thành thumbnail với kích thước 120 * 120:

location ~ /images/.*\.jpg$ {
    image_filter  crop  120  120;
}

Mở rộng hơn ta sẽ cấu hình tính năng resize hoặc crop hình ảnh theo các bước sau : Kiểm tra sự hiện diện của các param được truyền vào, nếu không có ta trả lại hình ảnh gốc ban đầu

location ~ /images/.*\.jpg$ {
    if ($query_string ~ .*=.*) {
        rewrite ^/images/(.*\.jpg)$ /image_filter/$1 last;
    }
}

Kế tiếp ta sẽ kiểm tra action truyền vào là resize hay crop, mặc định sẽ là crop :

if ($arg_action = "resize") {
    rewrite ^ /resize last;
}

rewrite ^ /crop last;

Ứng với action là resize hay crop ta sẽ trả về hình ảnh được chuyển đổi.

image_filter resize $width $height;
image_filter crop $width $height;

Trong trường hợp bộ lọc hình ảnh không xử lý được thì lỗi 415 sẽ xảy ra, chúng ta sẽ thay thế bằng 1 hình ảnh GIF có kích thước 1x1 px. Dưới đây là một cấu hình hoàn chỉnh với bộ lọc hình ảnh :

server {
    listen  	80;
    server_name your_domain.com;
    root /usr/share/nginx/html/images/;

    location ~ /images/.*\.jpg$ {
        if ($query_string ~ .*=.*) {
          rewrite ^/images/(.*\.jpg)$ /image_filter/$1 last;
        }
    }

    location / {
    }

    location ~ ^/image_filter/(.*\.jpg)$ {
        internal;
        set $file $1;
        set $width 120;
        set $height 120;
        set $quality 75;

        if ($arg_width ~ (\d*)) {
            set $width $1;
        }

        if ($arg_height ~ (\d*)) {
            set $height $1;
        }

        if ($arg_quality ~ (100|[1-9][0-9]|[1-9])) {
            set $quality $1;
        }

        if ($arg_type = "resize") {
            rewrite ^ /resize last;
        }

        rewrite ^ /crop last;
    }

    location /resize {
        internal;
        rewrite ^ /images/$file break;
        image_filter  resize  $width $height;
        image_filter_jpeg_quality $quality;
        error_page 415 = @empty;
    }

    location /crop {
        internal;
        rewrite ^ /images/$file break;
        image_filter  crop  $width $height;
        image_filter_jpeg_quality $quality;
        error_page 415 = @empty;
    }

    location @empty {
        empty_gif;
    }
}

Ok, bây giờ bạn có thể khỏi động lại nginx và tận hưởng thành quả

service nginx restart

Bạn có thể truy cập đương dẫn này đế test

http://your_domain.com/images/product1.jpg?width=200&height=120&action=resize http://your_domain.com/images/product1.jpg?width=200&height=120&action=crop http://your_domain.com/images/product1.jpg?width=200&height=200&action=crop&quality=110

Khi bạn apply xử lý này lên trang production thì nên bật cache lên để lưu cache cho mỗi lần request đảm bảo tối ưu tốc độ website của bạn

Bằng việc sử dụng bộ lọc hình ảnh với nginx ta có thể dễ dàng thay đổi kích thước và chất lượng của hình ảnh sao cho phù hợp với yêu cầu và mục đích sử dụng, qua đó nó giúp chúng ta cải thiện được tốc độ khi lướt web.

Tham khảo

http://nginx.org/en/docs/http/ngx_http_image_filter_module.html


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí