New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for vips in the image analyzer #42005
Conversation
activestorage/lib/active_storage/analyzer/image_analyzer/image_magick.rb
Outdated
Show resolved
Hide resolved
@@ -192,7 +192,7 @@ def process_variants_with(processor) | |||
previous_processor, ActiveStorage.variant_processor = ActiveStorage.variant_processor, processor | |||
yield | |||
rescue LoadError | |||
skip "Variant processor #{processor.inspect} is not installed" | |||
ENV["CI"] ? raise : skip("Variant processor #{processor.inspect} is not installed") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm probably missing it - what's the reasoning behind this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I originally opened this PR all my vips tests were failing in the CI, even though they passed on the dev box. I got the help of @matthewd and we discovered that the CI environment did not have VIPS installed, and therefore the tests for vips were not running. He asked me to ensure that all vips tests raised errors in the CI, but were allowed to be skipped in contributor's machines to make development easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the tests are passing now, I assume that means vips has been installed in CI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just re-approved the CI to run, let us know if theres any other blockers! 🙇
Changes made. Tests passed. There is an error in "Guides" but it seems it is unrelated, and Github says the build passed? There's 2 workflows awaiting approval. What should I do in this case? |
@brenogazzola In the case where workflows are awaiting approval, one of us has to approve to run the CI 😢 Running again but I think based on your last comment we should be good! |
@@ -24,7 +26,7 @@ class Engine < Rails::Engine # :nodoc: | |||
|
|||
config.active_storage = ActiveSupport::OrderedOptions.new | |||
config.active_storage.previewers = [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ] | |||
config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer, ActiveStorage::Analyzer::VideoAnalyzer ] | |||
config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer::Vips, ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick, ActiveStorage::Analyzer::VideoAnalyzer ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it could a breaking change. What happens on this branch if you try to use ActiveStorage::Analyzer::ImageAnalyzer
directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is. I didn't think about that. I can return my previous code, but it was looking pretty ugly:
def metadata
if ActiveStorage.variant_processor == :vips
Analyzer::ImageAnalyzer::Vips.new(@blob).metadata
else
Analyzer::ImageAnalyzer::ImageMagick.new(@blob).metadata
end
end
It also does not fit the pattern that was set with the PDF previewers, where each lib is a different previewer in the array, instead of having a generic PDFPreviewer
that then chooses the correct class based on the libs available:
config.active_storage.previewers = [
ActiveStorage::Previewer::PopplerPDFPreviewer,
ActiveStorage::Previewer::MuPDFPreviewer,
ActiveStorage::Previewer::VideoPreviewer
]
I'm not sure where to go from here: breaking change, different patterns, or changing the previewers to have a generic PDFPreviewer
that then decides between mu
and poppler
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've also just noticed I am not respecting the naming pattern and should probably have named the analyzers VipsImageAnalyzer
and ImageMagickImageAnalyzer
so they match the way the previewers are named.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or I could return the original ImageAnalyzer
and just add the VipsVersion ahead of it:
config.active_storage.analyzers = [
ActiveStorage::Analyzer::VipsImageAnalyzer,
ActiveStorage::Analyzer::ImageAnalyzer,
ActiveStorage::Analyzer::VideoAnalyzer
]
This would not be a breaking change and it would more or less follow the way the previewers are set. I'd just need another class to place the common metadata
method so it stayed DRY.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the approach here is good, and if users have been doing things like config.active_storage.analyzers << MyAnalyzer
then it shouldn't cause problems. The risk I can think of is code like config.active_storage.analyzers.insert(config.active_storage.analyzers.index(ActiveStorage::Analyzer::ImageAnalyzer) + 1, MyAnalyzer)
breaking. Which seems like a bad pattern anyway.
Can you please update the docs: https://github.com/rails/rails/blob/main/guides/source/configuring.md#configuring-active-storage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I've also updated the comments in the code. Unfortunately, the CI failed on the same place as last time (the bug report templates I think)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you might need @zzak to approve it again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brenogazzola @ghiculescu Approved! 🙏
@brenogazzola Can you rebase and squash please? 🙇 |
87df9c4
to
b4b7c6c
Compare
@brenogazzola Now that #42392 was merged hopefully this will be easier to rebase, sorry I missed that until now 🙇 |
b4b7c6c
to
6dec647
Compare
@zzak It's fine. It's my own fault for opening multiple PRs for the same feature in the Rails at the same time. I'll keep rebasing as needed. |
Also, done. |
a1ff72c
to
6251ec2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brenogazzola if can you rebase this, then I'll merge 👍🏻
6251ec2
to
82fdf45
Compare
@pixeltrix Rebased. 👍 |
@brenogazzola thanks! 👍🏻 |
Thanks for fixing my issues @brenogazzola! |
It appears that with this change away from ImageMagick, the analyzer does not store the image's I had a test like this which used to pass before I started to migrate to Rails 7.0.0.rc3: test "poster is attached" do
content = contents(:blog_post_1)
assert content.poster.attached?
blob = content.poster.blob.tap(&:analyze)
assert_equal "cover.jpg", blob.filename.to_s
assert_equal "image/jpeg", blob.content_type
assert_equal({ identified: true, width: 1600, height: 900, analyzed: true }, # <-- Test fails here
blob.metadata.symbolize_keys)
assert_equal 211486, blob.byte_size
assert_equal "gDjkvuzYz1oUlbJ9hjbd5w==", blob.checksum
assert_equal "public", blob.service_name
end |
Active Storage has tests specifically to ensure that While upgrading, did you notice that Vips has become the new default in Rails 7.0? It's possible that you don't have Vips installed and this is causing the analyzer to fail. |
I am using Vips already in my 6.1.4 app. I will try to dig deeper to see why those width/height are disappearing in my test. |
Is it happening to all images or only some of them? There are 3 1 - All of them generate log when hit. Try going to |
Thanks for your suggestions. After upgrading my local vips binary ( |
Summary
Fixes: #41940
Fixes: #41941
Adds support for using vips as an image analyzer in active storage.
Other Information
This is pretty much my first non trivial PR, so advice on how to improve this is welcome. Just trying to get the ball running on this one, since I'd like to use this too.