rails: Vips::Error: No known saver for '/tmp/image_processing20200724-11554-lsl5p1.jfif'

Steps to reproduce

class SomeModel < ApplicationRecord
  has_one_attached :file
end

model = SomeModel.create!
model.file.attach(io: File.open('image.jfif'), filename: 'image.jfif', content_type: 'image/jpeg')
model.file.representation({resize_to_fit: [1920, 1920]}).processed

Expected behavior

Generate a representation

Actual behavior

Error:
CollectionTest#test_jfif_file_format:
Vips::Error: No known saver for '/tmp/image_processing20200724-11554-lsl5p1.jfif'.

System configuration

Rails version: 6.0.3.1

Ruby version: 2.5.1p57

Used image: image.zip

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 1
  • Comments: 24 (12 by maintainers)

Most upvoted comments

@pranavrajs you are correct.

@georgeclaghorn to me the issue should be reopened because it is not fixed.

I had a similar issue and, while this is not a permanent fix, it does help fixing the existing data so VIPs can handle the image processing:

ActiveStorage::Blob.where("filename ILIKE ?", "%.jfif").find_each do |blob|
	blob.update!(filename: blob.filename.to_s.gsub(/\.jfif/i, '.jpeg'))
end

@phylor it is not really fixed in 6.1. When you use vips you can get the error:

A Vips::Error occurred in background at 2023-09-09 02:33:04 UTC :

  VipsForeignSave: "/tmp/image_processing20230909-39-s4f4a0.jfif" is not a known file format
VipsForeignSave: "/tmp/image_processing20230909-39-s4f4a0.jfif" is not a known file format

  /var/app/current/vendor/bundle/ruby/3.0.0/gems/ruby-vips-2.1.4/lib/vips/image.rb:590:in `write_to_file'

This is because vips does not know the extension. When you call a representation you can ask for a specific format like this: item.file.representation({ resize_to_fit: [1920, 1920], format: :jpeg }).

@zzak and everyone involved https://github.com/libvips/libvips/issues/3775 . It will be released in 8.15.1 ( not released yet)

@casperbrike Thank you! I was just talking with @chaadow last night about reporting this upstream before trying to make any changes to Rails, so you saved us a ton. 🙏

Recently we stumbled upon similar issue and discovered that the root cause lies inside libvips. According to backtrace, Active Storage tries to call Vips::Image#write_to_file method, this method in turn calls vips_foreign_find_save function from libvips and the function raises VipsForeignSave error for JFIF images. Interestingly, libvips does support JFIF format, for example it’s possible to convert from JPG to JFIF and vice versa using CLI:

vips jpegsave img.jfif converted.jpg
vips jpegsave converted.jpg converted.jfif

So I’d say it’s not really a issue with Active Storage and it’d be better to address it at libvips level. I’ve already created an issue at their repo: https://github.com/libvips/libvips/issues/3775

For all Googlers: upgrading to Rails 6.1 solves this issue.

Edit: #40226 fixed issues when having no content type (and released in 6.1). This issue here is specifically about JFIF support, which hasn’t been implemented yet.

@johan-smits I didn’t fully review the issue and the current active storage implementation but what you mention should be doable, although using the last part of the content type is not possible in all the scenarios since it doesn’t necessarily match with the correct extension.

I will investigate it deeper at some point to see if rails can handle it.