12/08/2018, 14:46

Crop ảnh động GIF với MINIMAGICK

I.Mở đầu Thông thường ảnh avatar sẽ được tự động cắt cho phù thợp theo mặc định của mỗi web. Tuy nhiên, việc tự động cắt đó vẫn chưa thỏa mãn yều cầu người dùng nên có một số web thêm tính năng cho người dùng có thể tự chỉnh sử avatar của minh. Với việc này chúng ta có thể dùng thư viện jQuery ...

I.Mở đầu

Thông thường ảnh avatar sẽ được tự động cắt cho phù thợp theo mặc định của mỗi web. Tuy nhiên, việc tự động cắt đó vẫn chưa thỏa mãn yều cầu người dùng nên có một số web thêm tính năng cho người dùng có thể tự chỉnh sử avatar của minh. Với việc này chúng ta có thể dùng thư viện jQuery plugin Croppie. Chẳng may lại gặp tính huống khi user upload một ảnh động GIF. Khi crop một ảnh đơn frame thì ảnh sẽ được thay đổi đúng kích thước như móng muốn của người dùng nhưng lại khi crop một ảnh động GIF chỉ crop mỗi frame mà không phải ảnh với canvas gốc cho nên không thay đổi kích thước của ảnh động.

II.Thực hiện cắt bằng crop()

Chúng ta có một ảnh động sau:

test_GIF
    /robot.gif
    /crop_gif.rb

Phương thức đơn giản nhất để cắt ảnh là crop("WxH+X+Y");

# test_GIF/crop_gif.rb
require "mini_magick"
require "rmagick"

crop_w, crop_h, crop_x, crop_y  = [200, 149, 100, 0]
size = "#{crop_w}x#{crop_h}"
offset = "#{crop_x}+#{crop_y}"
image = MiniMagick::Image.open("robot.gif")
image.crop("#{size}+#{offset}")
image.write("output.gif")

Trong terminal cd test_GIF ruby crop_gif.rb

Kết quả ảnh động sau khi cắt

III.Cải thiện việc xử lý ảnh

Kích thước ảnh không đổi là do vấn đề nằm ở chỗ khi chúng ta cắt ảnh động GIF các bước thì qua mỗi frame, nó chỉ cắt frame mà không phải canvas. Cách nhanh nhất để giải quyết thì phải tuần theo đối số convert của ImageMagick

-coalesce -repage 0x0 -crop 200x149+100+0 +repage

Chúng ta sẽ sửa code thành như sau:

require "mini_magick"
require "rmagick"

crop_w, crop_h, crop_x, crop_y  = [200, 149, 100, 0]
size = "#{crop_w}x#{crop_h}"
offset = "#{crop_x}+#{crop_y}"
image = MiniMagick::Image.open("robot.gif")
+ image.coalesce
+ image.repage("0x0")
image.crop("#{size}+#{offset}")
+ image << "+repage"
+ image.write("good_output.gif")

Cuối cùng chúng ta đặt được kết quả như móng muốn

IV.Kết luận

Tuy đây chỉ là bài viết ngắn nhưng nó lại có thể giúp các bạn được khi gặp tính huống như trên.

0