diff options
Diffstat (limited to 'activestorage/app')
-rw-r--r-- | activestorage/app/models/active_storage/blob.rb | 6 | ||||
-rw-r--r-- | activestorage/app/models/active_storage/variant.rb | 37 |
2 files changed, 37 insertions, 6 deletions
diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb index fdf17ac67e..3b48ee72af 100644 --- a/activestorage/app/models/active_storage/blob.rb +++ b/activestorage/app/models/active_storage/blob.rb @@ -172,11 +172,11 @@ class ActiveStorage::Blob < ActiveRecord::Base end - # Returns an ActiveStorage::Preview instance for a previewable blob or an ActiveStorage::Variant instance for an image blob. + # Returns an ActiveStorage::Preview for a previewable blob or an ActiveStorage::Variant for a variable image blob. # # blob.representation(resize: "100x100").processed.service_url # - # Raises ActiveStorage::Blob::UnrepresentableError if the receiving blob is neither an image nor previewable. Call + # Raises ActiveStorage::Blob::UnrepresentableError if the receiving blob is neither variable nor previewable. Call # ActiveStorage::Blob#representable? to determine whether a blob is representable. # # See ActiveStorage::Blob#preview and ActiveStorage::Blob#variant for more information. @@ -191,7 +191,7 @@ class ActiveStorage::Blob < ActiveRecord::Base end end - # Returns true if the blob is variable or is previewable. + # Returns true if the blob is variable or previewable. def representable? variable? || previewable? end diff --git a/activestorage/app/models/active_storage/variant.rb b/activestorage/app/models/active_storage/variant.rb index fa5aa69bd3..8909fd628a 100644 --- a/activestorage/app/models/active_storage/variant.rb +++ b/activestorage/app/models/active_storage/variant.rb @@ -35,6 +35,8 @@ # # avatar.variant(resize: "100x100", monochrome: true, flip: "-90") class ActiveStorage::Variant + WEB_IMAGE_CONTENT_TYPES = %w( image/png image/jpeg image/jpg image/gif ) + attr_reader :blob, :variation delegate :service, to: :blob @@ -62,7 +64,7 @@ class ActiveStorage::Variant # for a variant that points to the ActiveStorage::VariantsController, which in turn will use this +service_call+ method # for its redirection. def service_url(expires_in: service.url_expires_in, disposition: :inline) - service.url key, expires_in: expires_in, disposition: disposition, filename: blob.filename, content_type: blob.content_type + service.url key, expires_in: expires_in, disposition: disposition, filename: filename, content_type: content_type end # Returns the receiving variant. Allows ActiveStorage::Variant and ActiveStorage::Preview instances to be used interchangeably. @@ -76,11 +78,40 @@ class ActiveStorage::Variant end def process - service.upload key, transform(service.download(blob.key)) + service.upload key, transform(blob.download) + end + + + def filename + if WEB_IMAGE_CONTENT_TYPES.include?(blob.content_type) + blob.filename + else + ActiveStorage::Filename.new("#{blob.filename.base}.png") + end end + def content_type + blob.content_type.presence_in(WEB_IMAGE_CONTENT_TYPES) || "image/png" + end + + def transform(io) + read_image_from(io) do |image| + mogrify image + format image + end + end + + def read_image_from(io, &block) require "mini_magick" - File.open MiniMagick::Image.read(io).tap { |image| variation.transform(image) }.path + File.open MiniMagick::Image.read(io).tap(&block).path + end + + def mogrify(image) + variation.transform(image) + end + + def format(image) + image.format("PNG") unless WEB_IMAGE_CONTENT_TYPES.include?(blob.content_type) end end |