mirror of https://github.com/rails/rails
Convert non-web image (e.g. PSD) variants to PNG
This commit is contained in:
parent
daf15f58b9
commit
95117a2ce2
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -4,12 +4,9 @@ require "test_helper"
|
|||
require "database/setup"
|
||||
|
||||
class ActiveStorage::VariantTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@blob = create_file_blob filename: "racecar.jpg"
|
||||
end
|
||||
|
||||
test "resized variation" do
|
||||
variant = @blob.variant(resize: "100x100").processed
|
||||
test "resized variation of JPEG blob" do
|
||||
blob = create_file_blob(filename: "racecar.jpg")
|
||||
variant = blob.variant(resize: "100x100").processed
|
||||
assert_match(/racecar\.jpg/, variant.service_url)
|
||||
|
||||
image = read_image(variant)
|
||||
|
@ -17,8 +14,9 @@ class ActiveStorage::VariantTest < ActiveSupport::TestCase
|
|||
assert_equal 67, image.height
|
||||
end
|
||||
|
||||
test "resized and monochrome variation" do
|
||||
variant = @blob.variant(resize: "100x100", monochrome: true).processed
|
||||
test "resized and monochrome variation of JPEG blob" do
|
||||
blob = create_file_blob(filename: "racecar.jpg")
|
||||
variant = blob.variant(resize: "100x100", monochrome: true).processed
|
||||
assert_match(/racecar\.jpg/, variant.service_url)
|
||||
|
||||
image = read_image(variant)
|
||||
|
@ -27,6 +25,17 @@ class ActiveStorage::VariantTest < ActiveSupport::TestCase
|
|||
assert_match(/Gray/, image.colorspace)
|
||||
end
|
||||
|
||||
test "resized variation of PSD blob" do
|
||||
blob = create_file_blob(filename: "icon.psd", content_type: "image/vnd.adobe.photoshop")
|
||||
variant = blob.variant(resize: "20x20").processed
|
||||
assert_match(/icon\.png/, variant.service_url)
|
||||
|
||||
image = read_image(variant)
|
||||
assert_equal "PNG", image.type
|
||||
assert_equal 20, image.width
|
||||
assert_equal 20, image.height
|
||||
end
|
||||
|
||||
test "variation of invariable blob" do
|
||||
assert_raises ActiveStorage::Blob::InvariableError do
|
||||
create_file_blob(filename: "report.pdf", content_type: "application/pdf").variant(resize: "100x100")
|
||||
|
@ -34,7 +43,8 @@ class ActiveStorage::VariantTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test "service_url doesn't grow in length despite long variant options" do
|
||||
variant = @blob.variant(font: "a" * 10_000).processed
|
||||
blob = create_file_blob(filename: "racecar.jpg")
|
||||
variant = blob.variant(font: "a" * 10_000).processed
|
||||
assert_operator variant.service_url.length, :<, 500
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue