module ActiveStorage::Blob::Representable

def create_preview_image_later(variations) # :nodoc:

:nodoc:
def create_preview_image_later(variations) # :nodoc:
  ActiveStorage::PreviewImageJob.perform_later(self, variations) if representable?
end

def default_variant_format

def default_variant_format
  if web_image?
    format || :png
  else
    :png
  end
end

def default_variant_transformations

def default_variant_transformations
  { format: default_variant_format }
end

def format

def format
  if filename.extension.present? && Marcel::MimeType.for(extension: filename.extension) == content_type
    filename.extension
  else
    Marcel::Magic.new(content_type.to_s).extensions.first
  end
end

def preprocessed(transformations) # :nodoc:

:nodoc:
def preprocessed(transformations) # :nodoc:
  ActiveStorage::TransformJob.perform_later(self, transformations) if representable?
end

def preview(transformations)

whether a blob is accepted by any previewer, call ActiveStorage::Blob#previewable?.
This method raises ActiveStorage::UnpreviewableError if no previewer accepts the receiving blob. To determine

<%= image_tag video.preview(resize_to_limit: [100, 100]) %>

how to use the built-in version:
Active Storage provides one, but you may want to create your own (for example, if you need authentication). Here’s
Avoid processing previews synchronously in views. Instead, link to a controller action that processes them on demand.

blob.preview(resize_to_limit: [100, 100]).processed.url

extracts the first frame from a video and the PDF previewer extracts the first page from a PDF document.
from a non-image blob. Active Storage comes with built-in previewers for videos and PDF documents. The video previewer
Returns an ActiveStorage::Preview instance with the set of +transformations+ provided. A preview is an image generated
def preview(transformations)
  if previewable?
    ActiveStorage::Preview.new(self, transformations)
  else
    raise ActiveStorage::UnpreviewableError
  end
end

def preview_image_needed_before_processing_variants? # :nodoc:

:nodoc:
def preview_image_needed_before_processing_variants? # :nodoc:
  previewable? && !preview_image.attached?
end

def previewable?

Returns true if any registered previewer accepts the blob. By default, this will return true for videos and PDF documents.
def previewable?
  ActiveStorage.previewers.any? { |klass| klass.accept?(self) }
end

def representable?

Returns true if the blob is variable or previewable.
def representable?
  variable? || previewable?
end

def representation(transformations)

See ActiveStorage::Blob#preview and ActiveStorage::Blob#variant for more information.

ActiveStorage::Blob#representable? to determine whether a blob is representable.
Raises ActiveStorage::UnrepresentableError if the receiving blob is neither variable nor previewable. Call

blob.representation(resize_to_limit: [100, 100]).processed.url

Returns an ActiveStorage::Preview for a previewable blob or an ActiveStorage::Variant for a variable image blob.
def representation(transformations)
  case
  when previewable?
    preview transformations
  when variable?
    variant transformations
  else
    raise ActiveStorage::UnrepresentableError
  end
end

def variable?

type is in +ActiveStorage.variable_content_types+).
Returns true if the variant processor can transform the blob (its content
def variable?
  ActiveStorage.variable_content_types.include?(content_type)
end

def variant(transformations)


saver: { subsample_mode: "on", strip: true, interlace: true, quality: 80 }) %>
<%= image_tag user.avatar.variant(resize_to_limit: [100, 100], format: :jpeg,


sampling_factor: "4:2:0", strip: true, interlace: "JPEG", colorspace: "sRGB", quality: 80) %>
<%= image_tag user.avatar.variant(resize_to_limit: [100, 100], format: :jpeg,


need to update processor-specific options:
If migrating an existing application between MiniMagick and Vips, you will

<%= image_tag user.avatar.variant(resize_to_fill: [100, 100, { crop: :centre }]) %>


processor-specific values which can be passed as a trailing hash:
Some options, including those listed above, can accept additional

user.avatar.variant(rotate: 90)

Rotates the image by the specified angle.
[+:rotate+]

user.avatar.variant(crop: [20, 50, 300, 300])

and height of the area to extract.
top edges of area to extract, while the last two arguments are the width
Extracts an area from an image. The first two arguments are the left and
[+:crop+]

user.avatar.variant(resize_and_pad: [100, 100])

transparent color if source image has alpha channel, black otherwise.
the original aspect ratio. If necessary, will pad the remaining area with
Resizes the image to fit within the specified dimensions while retaining
[+:resize_and_pad+]

user.avatar.variant(resize_to_fill: [100, 100])

dimension.
original aspect ratio. If necessary, will crop the image in the larger
Resizes the image to fill the specified dimensions while retaining the
[+:resize_to_fill+]

user.avatar.variant(resize_to_fit: [100, 100])

specified dimensions or upsize if it's smaller.
the original aspect ratio. Will downsize the image if it's larger than the
Resizes the image to fit within the specified dimensions while retaining
[+:resize_to_fit+]

user.avatar.variant(resize_to_limit: [100, 100])

the specified dimensions.
the original aspect ratio. Will only resize the image if it's larger than
Downsizes the image to fit within the specified dimensions while retaining
[+:resize_to_limit+]

However, both variant processors support the following options:
{MiniMagick}[https://github.com/janko/image_processing/blob/master/doc/minimagick.md].
{Vips}[https://github.com/janko/image_processing/blob/master/doc/vips.md] or
and depend on which variant processor you are using:
Options are defined by the {image_processing gem}[https://github.com/janko/image_processing],

==== Options

ActiveStorage::Blob#variable?.
transform the blob. To determine whether a blob is variable, call
Raises ActiveStorage::InvariableError if the variant processor cannot

can then produce on-demand.
This will create a URL for that specific blob with that specific variant, which the ActiveStorage::RepresentationsController

<%= image_tag Current.user.avatar.variant(resize_to_limit: [100, 100]) %>

specific variant that can be created by a controller on-demand. Like so:
Frequently, though, you don't actually want to transform the variant right away. But rather simply refer to a

Then it'll upload said variant to the service according to a derivative key of the blob and the transformations.
This will create and process a variant of the avatar blob that's constrained to a height and width of 100px.

avatar.variant(resize_to_limit: [100, 100]).processed.url

This is only relevant for image files, and it allows any image to be transformed for size, colors, and the like. Example:
Returns an ActiveStorage::Variant or ActiveStorage::VariantWithRecord instance with the set of +transformations+ provided.
def variant(transformations)
  if variable?
    variant_class.new(self, ActiveStorage::Variation.wrap(transformations).default_to(default_variant_transformations))
  else
    raise ActiveStorage::InvariableError
  end
end

def variant_class

def variant_class
  ActiveStorage.track_variants ? ActiveStorage::VariantWithRecord : ActiveStorage::Variant
end