Packages

File attachments for Ecto schemas

Current section

Files

Jump to
attached lib attached processors metadata_extractors image vix.ex
Raw

lib/attached/processors/metadata_extractors/image/vix.ex

defmodule Attached.Processors.MetadataExtractors.Image.Vix do
@moduledoc """
Extracts width and height from image files using libvips via the
`vix` package. Swaps dimensions for images rotated 90°/270° via EXIF.
"""
@behaviour Attached.Processors.MetadataExtractors.Behaviour
@compile {:no_warn_undefined, [Vix.Vips.Image]}
@image_types ~w(image/png image/jpeg image/gif image/webp image/tiff
image/bmp image/heic image/heif image/avif)
@impl true
def accept?(content_type), do: content_type in @image_types
@impl true
def available?, do: Code.ensure_loaded?(Vix.Vips.Image)
@impl true
def install_hint do
~s|Add `{:vix, "~> 0.31"}` to mix.exs deps — ships with a precompiled libvips NIF, no system packages needed.|
end
@impl true
def metadata(input_path) do
case Vix.Vips.Image.new_from_file(input_path) do
{:ok, image} ->
w = Vix.Vips.Image.width(image)
h = Vix.Vips.Image.height(image)
angle = exif_angle(image)
if angle in [90, 270],
do: %{width: h, height: w},
else: %{width: w, height: h}
_ ->
%{}
end
end
defp exif_angle(image) do
try do
case Vix.Vips.Image.header_get(image, "exif-ifd0-Orientation") do
{:ok, val} when val in [5, 6] -> 90
{:ok, val} when val in [7, 8] -> 270
_ -> 0
end
rescue
_ -> 0
end
end
end