Search code examples
ruby-on-railsrails-activestorage

Get metadata of Active Storage variant


I have an Active Storage image variant e.g.

<%= image_tag model.logo_image.variant(resize_to_fit: [300, 200]) %>

I'm trying to get the width and height values of this variant (since they are unknown) for use in the width and height HTML attributes.

I expected them to be here:

model.logo_image.variant(resize_to_fit: [300, 200]).processed.blob.metadata

But this gives me the metadata of the original file not the resized variant e.g.

{"identified"=>true, "width"=>800, "height"=>174, "analyzed"=>true}

How do I get the dimensions of an Active Storage variant?


Solution

  • With Rails 6.1, finally all Variations are stored in a new model/database table and each variation with a Blob. Try upgrading, if this feature is relevant for you.

    Very deep into the object, you can find then the variation blob, and thus the metadata, though!

    Try:

    model.logo_image.
     variant(resize_to_fit: [300, 200]).
     processed.send(:record).image.blob.metadata
    

    It does not work the first time though, when called first time, it has no width/height, because the AnalyzeJob will run asynchronously, and it will add the width/height "later", depending on your queue setup.

    Maybe add a helper_method that creates the image with width, height if available:

    module ApplicationHelper
      def image_tag_for_attachment_with_dimensions(variant, opts = {})
        if variant.processed?
          metadata = variant.processed.send(:record).image.blob.metadata
          if metadata['width']
            opts[:width] = metadata['width']
            opts[:height] = metadata['height']
          end
        end
        image_tag variant, opts
      end
    end
    
    # usage: 
    = image_tag_for_attachment_with_dimensions model.logo_image.variant(resize_to_fit: [300, 200])