Active Storage - some techniques

steve lee
·

Requirements

1. Get the dimension size of an image

For example, we have a model MediaAsset like this:

class MediaAsset < ApplicationRecord
  validates :media_file, presence: true
end

If the blob has been analyzed, you can access the image's dimension by:

media_file = MediaAsset.find(2).media_file
media_file.metadata
# => {"identified"=>true, "analyzed"=>true, "width"=>1000, "height"=>1017}
media_file.metadata["width"] # or height

You must call analyze() method if the blob hasn't been analyzed.

media_file.analyzed? # => false
media_file.analyze   

By default, analyze_later() is automatically called for a blob when it's attached for the first time.

2. Upload the remote file from URL

Just use open-uri to open the image from url and attach it as a local file:

require 'open-uri'
file = URI.open('https://www.balisafarimarinepark.com/wp-content/uploads/2019/07/leopard-bali-safari-park.jpg')
media_asset.media_file.attach(io: file, filename: 'some-image.jpg')

Or if you want to save with a filename:

uri = URI("https://www.balisafarimarinepark.com/wp-content/uploads/2019/07/leopard-bali-safari-park.jpg")
filename = File.basename(uri.path)
media_asset.media_file.attach(io: file, filename: filename)

3. Transform the image

You can crop, resize or rotate images by using variant method, here are some samples:

# Change the format of the image
media_file.variant(format: :jpg)

# Rotate the image 90°
media_file.variant(rotate: 90)

# Resizes the image to fill the specified dimensions while retaining the original aspect ratio.
# If necessary, will crop the image in the larger dimension.
media_file.variant(resize_to_limit: [500, 500])

# Resizes the image to fit within the specified dimensions while retaining the original aspect ratio.
# Will downsize the image if it's larger than the specified dimensions or upsize if it's smaller.
media_file.variant(resize_to_fit: [500, 500])

View more: https://edgeguides.rubyonrails.org/active_storage_overview.html#transforming-images

评论
登录后评论

open-uri 支持的范围比较大,容易被注入:

> URI.open '/tmp/test.txt'
=> #<File:/tmp/test.txt>
> URI.open('| ls')
=> #<IO:fd 7>

抓用户输入的时候建议校验 uri 的 schema,并且用别的 http 库(只支持 http)。

社区准则 博客 联系 社区 状态
主题