aboutsummaryrefslogtreecommitdiffstats
path: root/activestorage
diff options
context:
space:
mode:
Diffstat (limited to 'activestorage')
-rw-r--r--activestorage/app/models/active_storage/variant.rb37
-rw-r--r--activestorage/test/fixtures/files/icon.psdbin0 -> 37441 bytes
-rw-r--r--activestorage/test/models/variant_test.rb28
3 files changed, 53 insertions, 12 deletions
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
diff --git a/activestorage/test/fixtures/files/icon.psd b/activestorage/test/fixtures/files/icon.psd
new file mode 100644
index 0000000000..631fceeaab
--- /dev/null
+++ b/activestorage/test/fixtures/files/icon.psd
Binary files differ
diff --git a/activestorage/test/models/variant_test.rb b/activestorage/test/models/variant_test.rb
index 83ebce4446..8eced41ee0 100644
--- a/activestorage/test/models/variant_test.rb
+++ b/activestorage/test/models/variant_test.rb
@@ -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