The shape of a picture: ordinary, wide (a horizontal panorama) or tall (a vertical one, a Pinterest pin).
Shape is read from a file's aspect_ratio (width ÷ height, kept by Postgres,
V212), never from EXIF: no camera flag is involved, and an edit that crops or
rotates the photo changes its shape with no job to keep a flag right. Where wide
stops and panorama starts is a taste, so the two thresholds live here and are
the one place to change (a per-user setting would replace these constants):
- wide:
aspect_ratio >= 2.0(2:1 or wider); - tall:
aspect_ratio <= 0.5(1:2 or taller; a phone screenshot, at about 1:2.16, counts as tall).
Filtering
Shape.filter(File, :wide) # or :tall; nil / "all" leave it alone
Storage.list_files_in_scope(nil, shape: :wide)A file with no usable size (aspect_ratio nil) is neither.
Summary
Functions
The shape of a ratio, a {width, height} pair or anything carrying them (a
file); nil when there is no usable size.
Narrows a query over files (or anything with an aspect_ratio) to a shape.
nil, "all" and "" leave it unfiltered; :wide/"wide" and
:tall/"tall" filter; anything else raises, so a typo is not silently
"no filter".
A size in megapixels to one decimal: 4032 × 3024 is 12.2. 0.0 without a usable size.
The largest aspect_ratio of a tall picture.
The smallest aspect_ratio of a wide picture.
Types
Functions
The shape of a ratio, a {width, height} pair or anything carrying them (a
file); nil when there is no usable size.
@spec filter(Ecto.Queryable.t(), t() | String.t() | nil) :: Ecto.Query.t()
Narrows a query over files (or anything with an aspect_ratio) to a shape.
nil, "all" and "" leave it unfiltered; :wide/"wide" and
:tall/"tall" filter; anything else raises, so a typo is not silently
"no filter".
A size in megapixels to one decimal: 4032 × 3024 is 12.2. 0.0 without a usable size.
@spec tall_max() :: float()
The largest aspect_ratio of a tall picture.
@spec wide_min() :: float()
The smallest aspect_ratio of a wide picture.