+6

Giới thiệu về thư viện load ảnh Glide và so sánh với thư viện Picasso

Trong sự kiện Google Developer Summit Thailand, Google đã giới thiệu đến chúng ta một thư viện load ảnh mới dành cho Android được phát triển bởi bumptech với tên Glide, đây là một thư viện mà Google khuyên dùng. Nó đã được sử dụng trong nhiều dự án mã nguồn mở của Google đến nay bao gồm cả sự kiện chính thức Google I/O 2014.

Nó làm cho tôi cảm thấy thú vị. Tôi đã dành cả đêm để trải nghiệm nó và quyết định chia sẻ kinh nghiệm của tôi trong bài viết này. Và điều đầu tiên, tôi phải nói rằng nó có nét tương đồng tới 90% so với Picasso. Chính xác hơn, tôi nghĩ rằng nó dường như là một Picasso-clone.

Dù sao thì nó cũng khá khác nhau trong chi tiết. Bạn sẽ biết điều khác biệt đó là như thế nào.

Import vào dự án

Cả hai Picasso và Glide là trên jcenter. Bạn chỉ có thể dễ dàng import nó vào dependency của dự án của mình như bên dưới:

Picasso

  dependencies {
     compile 'com.squareup.picasso: picasso: 2.5.1'
 }

Glide

  dependencies {
     compile 'com.github.bumptech.glide: lướt: 3.5.2'
     compile 'com.android.support:support-v4:22.0.0'
 }

Dù sao Glide cũng cần thêm một thư viện hỗ trợ từ Android là Android Support Library v4, chú ý không quên import support-v4 vào ứng dụng của bạn. Điều này có lẽ sẽ không gặp phải vấn đề gì khi Android Support Library v4 đã trở nên cần thiết cho đa số các ứng dụng được phát triển ở thời điểm hiện tại.

Căn bản

Như đã nói ờ trên, Glide rất giống với Picasso. Cách để tải một hình ảnh vào một ImageView với Glide là khá giống như Picasso.

Picasso

  Picasso.with (context)
     .load ( "http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
     .into (ivImg);

Glide

  Glide.with (context)
     .load ( "http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
     .into (ivImg);

Mặc dù trông có vẻ khá giống nhau nhưng khi đi vào chi tiết thì Glide được thiết kế là tốt hơn nhiều khi phương thức with không chỉ cho phép tham số Context như Picasso mà còn có cả Activity và Fragment. Context sẽ được trích xuất ra một cách tự động từ các tham số mà bạn sử dụng để đưa vào phương thức with.

with.png

Và một lợi ích to lớn của Glide thực hiện trong Activity/Fragment là: việc tải ảnh sẽ được tích hợp cùng với vòng đời của Activity/Fragment, ví dụ: Glide sẽ tạm dừng tải ảnh khi Activity/Fragment đang ở trạng thái Paused, và nó sẽ tự động tiếp tục khi Activity/Fragment quay trở lại trạng thái Resumed. Vì vậy, nếu như có thể, tôi khuyến khích các bạn sử dụng Glide với các Activity/Fragment khác nhau chứ không chỉ một Context.

Mặc định Bitmap Format là RGB_565

Dưới đây là kết quả của việc tải ảnh so với Picasso. (Ảnh gốc có kích thước 1920x1080 pixel được tải về ImageView có kích thước 768x432 pixel)

firstload.jpg

Bạn có thể nhận thấy rằng chất lượng ảnh được tải bởi Glide có chất lượng kém hơn so với Picasso. Tại sao? Điều này là do Glide định dạng Bitmap mặc định có định dạng RGB_565, định dạng này sẽ chỉ chiếm 50% bộ nhớ so với định dạng ARGB_8888 .

Dưới đây là biểu đồ chiếm dụng bộ nhớ giữa Picasso với định dạng ARGB8888 và Glide tại RGB565. (Ứng dụng cơ sở chiếm dụng khoảng 8MB)

ram1_1.png

Bạn không cần phải làm bất cứ điều gì nếu như bạn ok với chất lượng của hình ảnh mặc định mà Glide đã lấy về. Nhưng nếu nghĩ rằng đó là không thể chấp nhận hoặc không đủ tốt cho bạn, bạn có thể chuyển đổi định dạng Bitmap sang ARGB_8888 bằng cách tạo ra một Class mới extend từ GlideModule như dưới đây

public class GlideConfiguration implements GlideModule {

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // Apply options to the builder here.
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        // register ModelLoaders here.
    }
}

Và sau đó định nghĩa nó là một meta-data bên trong AndroidManifest.xml

 <meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
        android:value="GlideModule"/>`

Giờ thì ảnh tải về trông nó có vẻ như đã tốt hơn trước rồi

quality2.jpg

Chúng ta hãy nhìn vào biểu đồ chiếm dụng bộ nhớ một lần nữa. Nó cho thấy rằng mặc dù Glide chiếm dụng gần 2 lần so với trước nhưng Picasso vẫn chiếm dụng một bộ nhớ lớn hơn nhiều so với Glide.

ram2_1.png

Lý do là Picasso tải hình ảnh kích thước đầy đủ (1920x1080 pixels) vào bộ nhớ và để cho GPU thực hiện việc thay đổi kích thước ảnh trong quá trình chương trình đang chạy. Trong khi Glide tải ảnh chính xác kích thước của ImageView (768x432 pixel) vào bộ nhớ và có lẽ đó là một cách xử lý rất hay. Dù sao bạn có thể thay đổi cách xử lý Picasso bằng cách sử dụng phương thức resize():

  Picasso.with(this)
    .load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
    .resize(768, 432)
    .into(ivImgPicasso);

Nhưng vấn đề là bạn cần phải tự tính toán kích thước của ImageView. Hoặc nếu ImageView của bạn có kích thước chính xác (không sử dụng wrap_content), bạn sẽ dễ dàng làm điều đó.

  Picasso.with(this)
    .load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
    .fit()
    .centerCrop()
    .into(ivImgPicasso);

biểu đồ chiếm dụng bộ nhớ bây giờ là cuối cùng gần như giống nhau!

memory3.png

Mặc dù chiếm dụng bộ nhớ là khá giống nhau nhưng tôi phải nói rằng Glide vẫn vượt trội hơn so với Picasso trong thời điểm này vì nó có thể tính toán kích thước ImageView một cách tự động trong mỗi một trường hợp riêng.

Chi tiết về chất lượng hình ảnh

Dưới đây là kết quả khi tôi đã cố gắng để phóng to một ImageView tới kích thước thực tế.

quality3.png

Đáng chú ý là hình ảnh được tải bởi Glide có một số điểm ảnh bị nhiễu và nó không là mịn như khi sử dụng Picasso. Và cho đến bây giờ, tôi vẫn không thể tìm ra cách rõ ràng để thay đổi thuật toán dành cho việc thay đổi kích thước hình ảnh.

Nhưng nếu bạn hỏi tôi đó là một điều tồi tệ? Tôi sẽ trả lời rằng đó không phải là điều quá phải chú trọng trong thực tế sử dụng. Chất lượng là chấp nhận được và bạn chỉ cần thiết lập định dạng Bitmap là ARGB_8888, đó là tất cả.

Disk Caching

Khải niệm về bộ nhớ đệm mặc định của Picasso và Glide là rất khác nhau. Từ ví dụ trên, cùng hình ảnh Full HD được tải vào ImageView với Picasso và Glide. Khi tôi kiểm tra thư mục bộ nhớ cache, nó chỉ ra rằng Glide cache các kích thước ImageView (768x432 pixel), trong khi Picasso lại cache một kích thước đầy đủ (1920x1080 pixel).

cache.jpg

Và đúng như thế, những pixel bị nhiễu cũng là do nguyên nhân từ đây mà có. Ngoài ra, nếu hình ảnh được tải với định dạng RGB565, hình ảnh lưu trữ cũng sẽ chịu định dạng RGB565.

Khi tôi cố gắng điều chỉnh ImageView với kích cỡ khác nhau. Kết quả là dù cho kích thước của ImageView là thế nào, Picasso sẽ cache chỉ có kích thước duy nhất của hình ảnh, kích thước đầy đủ một. Còn Glide hoạt động khác, nó lưu trữ tập tin riêng biệt cho mỗi kích thước của ImageView. Mặc dù một hình ảnh đã được tải một lần nhưng nếu bạn cần phải tải kích thước khác cùng một hình ảnh, nó cần phải được tải xuống một lần nữa trước khi được thay đổi kích cỡ để giải quyết ngay và sau đó mới được lưu trữ.

Để làm rõ hơn, nếu có một ImageView trong trang đầu tiên với kích thước 200x200 pixel và có những ImageView khác ở trong trang thứ hai với 100x100 pixel và nó được hiển thị các hình ảnh tương tự. Bạn phải tải về các hình ảnh tương tự hai lần.

Dù sao thì bạn cũng có thể điều chỉnh hành động của nó bằng bộ nhớ cache Glide để các hình ảnh lấy về đủ kích thước và thay đổi kích cỡ một với lệnh dưới đây.

Glide.with(this)
     .load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
     .diskCacheStrategy(DiskCacheStrategy.ALL)
     .into(ivImgGlide);

Những hình ảnh tiếp theo được yêu cầu để hiển thị trên bất kỳ ImageView nào, hình ảnh đầy đủ kích thước sẽ được lấy ra từ bộ nhớ cache, thay đổi kích cỡ và sau đó lưu trữ.

Một điểm mạnh trong thiết kế của Glide là hình ảnh có thể được tải và hiển thị rất nhanh. Trong khi cách thực hiện của Picasso lại gây ra một số sự chậm trễ khi tải tải từ lúc nó cần phải thay đổi kích cỡ lần đầu tiên trước khi được thiết lập để hiện trên một ImageView dù rằng bạn có sử dụng dòng lệnh dưới đây để hiển ngay lập tức.

  // Picasso
 .noFade ();

Có những sự khác biệt trong cách thức lưu trữ bộ nhớ đệm giữa Glide và Picasso. Bạn có thể chọn cách thức phù hợp với yêu cầu của ứng dụng để ứng dụng của bạn được triển khai tốt nhất.

Đối với tôi, tôi thích Glide hơn Picasso vì nó nhanh hơn mặc dù nó cần nhiều không gian bộ nhớ để cache hình ảnh.

Tính năng

Bạn có thể làm hầu như tất cả những điều tương tự giống như Picasso có thể làm với cùng một phong cách mã hóa ví dụ,

Image Resizing

// Picasso
.resize(300, 200);

// Glide
.override(300, 200);

Center Cropping

// Picasso
.centerCrop();

// Glide
.centerCrop();

Transforming

// Picasso
.transform(new CircleTransform())

// Glide
.transform(new CircleTransform(context))

Thiết lập Placeholder và Error image

  // Picasso
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)

// Glide
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)

Như tôi đã nói, nếu bạn đã quen thuộc với Picasso, thì việc chuyển qua sử dung Glide sẽ dễ như nhai kẹo

Cái gì Glide có nhưng Picasso không

Khả năng tải ảnh GIF vào một ImageView đơn giản, đây có thể là tính năng thú vị nhất của Glide. Nhưng bạn không thể làm điều đó với Picasso.

Glide được thiết kế để làm việc hoàn hảo với vòng đời của Activity/Fragment nên các hình ảnh động sẽ được tự động dừng lại và tiếp tục cùng với trạng thái của Activity/Fragment.

Cách Glide cache ảnh vẫn có độ tượng tự, trước tiên là thay đổi kích thước sau đó lưu trữ.

Dù sao trong một phép đo tôi thấy rằng GIF Animation chiếm dụng khá nhiều bộ nhớ. Hãy sử dụng nó một cách khôn khéo.

Bên cạnh đó việc tải GIF Animation, Glide cũng có thể giải mã bất kỳ tập tin video dưới local để cho ra một hình ảnh tĩnh.

Một tính năng mà có thể có ích là bạn có thể thiết lập cách hình ảnh sẽ xuất hiện với một Animator (R.animator) trong khi Picasso chỉ có một hiệu ứng đó là Fade-in.

Điều cuối cùng, nếu bạn cần tạo một hình ảnh thu nhỏ của một hình ảnh mà bạn tải thì bạn có thể sử dụng phương thức thumbnail() .

Trên thực tế có một số tính năng khác mà bạn có thể chơi với nhưng hầu hết trong số họ không phải là quan trọng để sử dụng chung cho ví dụ, chuyển mã một hình ảnh vào mảng Byte, vv

Cấu hình

Bạn có thể điều chỉnh rất nhiều cấu hình cho ví dụ, kích thước và vị trí của bộ nhớ đệm đĩa, giới hạn tối đa của bộ nhớ đệm, định dạng Bitmap và nhiều hơn nữa.

Kích thước của thư viện

Picasso (v2.5.1) có kích thước khoảng 118KB trong khi Glide (v3.5.2) là khoảng 430KB.

librarysize.png

Dù sao sự khác biệt 312KB thể không phải là quá lớn.

số phương thức của Picasso và Glide tương ứng là 840 và 2678.

methodcount.png

Tôi phải nói rằng năm 2678 là khá nhiều với 65.535 phương thức (giới hạn của tập tin Android DEX). ProGuard khuyến cáo nên được bật nếu bạn chọn Glide. (Và bạn nên bật tính năng này cho tất cả cho tất cả các ứng dụng).

Phần kết luận

Cả Glide cũng không Picasso là hoàn hảo. Cách Glide tải một hình ảnh vào bộ nhớ và làm bộ nhớ đệm là tốt hơn so với Picasso mà để cho một hình ảnh được tải nhanh hơn. Ngoài ra, nó cũng giúp ngăn chặn một ứng dụng bị OutOfMemoryError liên tục. Tải GIF Animation là một tính năng được bá đạo được cung cấp bởi Glide. Nhưng dù sao Picasso giải mã một hình ảnh với chất lượng tốt hơn so với Glide.

Vậy tôi thích sử dụng thư viện nào? Mặc dù tôi sử dụng Picasso trong một thời gian rất dài như vậy, nhưng tôi phải thừa nhận rằng tôi bây giờ thích Glide. Nhưng tôi sẽ đề nghị bạn thay đổi định dạng Bitmap sang ARGB_8888 và để Glide cache cả hình ảnh đầy đủ kích thước và thay đổi kích cỡ đầu tiên. Nó sẽ làm công việc của bạn trở nên tốt hơn.

Nguồn tham khảo

Không có quá nhiều nguồn tham khảo trực tuyến liên quan đến Glide. Nhưng đây là những gì tôi tìm thấy.

Nguồn bài viết : https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en


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í