Quay lại
Tối ưu hóa ảnh trong laravel

Hôm nay mình sẽ hướng dẫn các bạn cách nén file ảnh để tiết kiệm dung lượng và làm tăng tốc độ truyền tải nhé, việc sử dụng dữ liệu ngày càng tăng trong khi storage lưu trữ thì ngày càng giảm bởi vì chúng ta lưu trữ quá nhiều files và dữ liệu, điển hình là với những website có nhiều ảnh mà không được tối ưu hóa, dẫn đến storage bị đầy và tốc độ truyền tải bị chậm để giải quyết được vấn đền này thì chúng ta nên nén hình ảnh trước khi lưu thì nó có thể giảm lưu trữ dữ liệu, vì nó cho phép bạn lưu trữ thông tin hình ảnh ở kích thước nhỏ hơn nhiều!

Trong hướng dẫn này, mình sẽ hướng dẫn các bạn cách nén hình ảnh đã tải lên trong Laravel bằng cách sử dụng package Intervention/image .

Image compression (Nén hình ảnh ) là gì?

Như mình có đọc trên Wikipedia, thì nén ảnh có nghĩa là :

  • A type of data compression applied to images to reduce their cost of storage and transmission.

Dịch nôm na nó có nghĩa là "Một kiểu nén dữ liệu được áp dụng cho hình ảnh để giảm chi phí lưu trữ và truyền tải."

Việc nén hình ảnh sẽ giảm số byte mà không làm giảm chất lượng của hình ảnh. Việc giảm kích thước tệp sẽ giảm cả yêu cầu về băng thông lưu trữ và truyền dẫn.

Để rõ và sâu hơn nữa mình chia làm 2 loại cho các bạn dễ hiểu nè 

Có hai hình thức nén hình ảnh: losslesslossy.

Nén lossy và lossless là gì?

  • lossless (Nén không mất dữ liệu): Thuật toán này cho phép giảm kích thước hình ảnh mà không làm giảm chất lượng. Nén không mất dữ liệu có ích khi dữ liệu hình ảnh gốc cần thiết cho mục đích tham khảo hoặc chỉnh sửa.
  • lossy (Nén mất dữ liệu): Có thể nén hình ảnh rất nhiều nhưng thông tin về hình ảnh sẽ bị mất do kích thước bị giảm trong quá trình nén.

Mình có đọc một bài post thì các chuyên gia khuyên rằng là khi xây dựng một nền tảng đã được nhiều người dùng truy cập, tốt nhất nên sử dụng tính năng nén lossy thay vì sử dụng lossless.

Với mục đích của việc nén thì nó phục vụ cho 2 mục đính sau:

  • Reduced storage cost (giảm chi phí lưu trữ): Tải lên hình ảnh theo thời gian sẽ tích tụ thành mức tiêu thụ lớn dung lượng lưu trữ được phân bổ để chạy ứng dụng và do đó, yêu cầu nhiều dung lượng lưu trữ hơn để ứng dụng chạy trơn tru. Bằng cách triển khai thuật toán nén hình ảnh, chi phí được cắt giảm do kích thước hình ảnh giảm đáng kể khi tải lên hình ảnh.
  • Reduced load time (Giảm thời gian tải) : Các nội dung như hình ảnh cần nhiều thời gian hơn để tải so với tệp JSON hoặc tệp văn bản. Điều này góp phần làm tăng thời gian tải trang và phản hồi chậm. Nếu hình ảnh được nén lại thì giúp giải quyết vấn đề vì chúng cần ít thời gian tải hơn.

Laravel xử lý nén hình ảnh như thế nào?

Trong Laravel, hình ảnh được đọc và thao tác bằng các thư viện phổ biến như GDiMagick và các thư viện khác tùy thuộc vào loại hình ảnh và chức năng bạn muốn có.

Thư viện GD cho phép bạn lấy loại hình ảnh và kích thước tệp, thao tác với pixel của hình ảnh và thậm chí tạo hình ảnh mới. iMagick có thể tạo, chỉnh sửa và compose hình ảnh và hỗ trợ nhiều loại hình ảnh, bao gồm JPG, PNG, GIF và SVG.

Intervention/image tích hợp hai thư viện phổ biến này và làm cho việc nén hình ảnh trở nên dễ hiểu và dễ triển khai hơn trong một dự án Laravel.

Cách cài đặt và sử dụng Intervention trong laravel

Trong bài hướng dẫn này, chúng ta sẽ sử dụng thư viện Intervention PHP và gói Intervention/image với Laravel để tải lên một hình ảnh và nén nó.

Để bắt đầu, hãy mở terminal và chạy lệnh bên dưới để tạo ứng dụng Laravel.

composer create-project laravel/laravel laravel_image_compression
cd laravel_image_compression

Tiếp theo, chúng ta phải cài đặt Intervention/image package. Để làm điều đó, hãy chạy lệnh sau:

composer require intervention/image

Khi đã cài đặt thành công, tiếp theo, hãy cập nhật Service Provider để tích hợp Intervention package, bằng cách cập nhật config/app.php, như bên dưới đây nhé :

return [
  ...
  'providers' => [
    ...
    \Intervention\Image\ImageServiceProvider::class,
  ],
  'aliases' => Facade::defaultAliases()->merge([
        ...
        'Image' => \Intervention\Image\Facades\Image::class,
    ])->toArray(),
]

Sau đó tạo một Controller để xử lý nén trong này nhé ! dùng cmd bên dưới để tạo Controller

php artisan make:controller ImageController

Sau đó, trong tệp controller mới được tạo, app\Http\Controller\ImageController.php, chúng ta có thể tạo một hàm và thêm logic của mình vào đó nhé !

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ImageController extends Controller 
{
    public function compressImage(Request $request) 
    {
        $this->validate($request, [
            'image' => 'required|image|mimes:jpg,jpeg,png,gif,svg|max:2048'
        ]);

        $image = $request->file['image'];
        /* 
            Chú ý: Dùng $image = base64_decode($request['image'])
           // nếu hình ảnh được gửi dưới dạng được mã hóa base64.        */
        $image_name = time().'_'.$image->getClientOriginalName();
        $path = public_path('uploads/') . "/" . $image_name;

        Image::make($image->getRealPath())->resize(150, 150)->save($path);
      
        return response()->json(
            [
                'data' => 'Image compressed and added'
            ], 
            201
        );
    }
}

Chúng ta cần phải import Image Facade để truy xuất hình ảnh và thay đổi kích thước hình ảnh . Sau đó thì chúng ta có thể viết chức năng nén và tải ảnh lên trong hàm compressImage().

Các bước sẽ được thực hiện như sau :

  1. Validate hình ảnh được tạo để đảm bảo rằng hình ảnh đã tải lên không lớn hơn 2048 byte và được giới hạn ở các tệp JPEG, GIF, PNG và SVG.
  2. Đường dẫn của hình ảnh được lấy bằng hàm getRealPath()
  3. Hình ảnh sau đó được thay đổi kích thước thành chiều rộng và chiều cao là 150.
  4. Sau đó, save hình ảnh

Bây giờ, tạo một thư mục mới có tên uploads trong thư mục public. Điều này sẽ cho phép ứng dụng lưu trữ hình ảnh ở đó.

chúng ta sẽ tạo một route sẽ kết nối với controller để xử lý và nén hình ảnh. Chúng ta đang mong đợi một request dưới dạng API, vì vậy chúng ta sẽ thêm vào routes/api.php, như trong ví dụ bên dưới này nhé !

...
use App\Http\Controllers\ImageController;

...
Route::post('/image-compress', [ImageController::class, 'compressImage']);

Ok bước cuối cùng là chạy thử thui nào !

Để kiểm tra, chúng ta sẽ sử dụng Postman. Tuy nhiên, trước khi làm như vậy, ứng dụng cần được khởi động. Để làm điều đó, hãy chạy đoạn mã dưới đây:

php artisan serve

Sau đó, mở Postman và đặt URL requestu thành http:/127.0.0.1:8000/api/image-compress và thay đổi phương thức HTTP từ GET thành POST. Sau đó, trong tab Body => trong cái drop-down thì chọn forrm-data, trước khi thêm hình ảnh vào request thì các bạn thêm Key Value nhé !

  • Key là tên field trong ví dụ này mình đặt là image
  • Trong cột Value, nhấp vào Chọn tệp, thao tác này sẽ mở ra hộp thoại chọn tệp. Tại đây, chọn một hình ảnh mà bạn muốn tải lên và nén, rồi đóng hộp thoại.

Bây giờ bạn đã sẵn sàng để tải hình ảnh lên Laravel, hãy nhẫn Send để gửi nhé !

Bạn có thể kiểm tra các thuộc tính của hình ảnh mới được thêm vào trong thư mục public/uploads để xem sự thay đổi về tỷ lệ cũng như sự giảm kích thước tệp.

kết luận

Trên đây là cách optimize ảnh khi bạn lưu trên server bằng cách sử dụng thư viện của PHP, bạn dễ dàng thực hiện được việc tối ưu đem lại những kết quả mong muốn. Giảm size nhưng vẫn đảm bảo chất lượng, ngoài ra nó còn hỗ trợ nhiều tính năng khác cho bạn sử dụng, chèn watermark hay crop v.v

Mình hy vọng bài viết đem lại sự hữu ích cho các bạn đang cần tìm kiếm cách tối ưng cho server của mình. Hẹn gặp lại trong bài viết sau! 

 

Bình luận (0)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday