Improve the image optimization pipeline with better compression and smarter variant generation: - Change to_lossless_webp → to_optimized_webp (lossy, quality 90) - Auto-resize uploads larger than 2000px to save storage - Skip pre-generating JPEG variants (~50% disk savings) - Add on-demand JPEG generation for legacy browsers (<5% of users) - Add /images/:id/variant/:width route for dynamic serving - Add VariantCache to supervision tree for startup validation - Add image_cache to static paths for disk-based serving The pipeline now stores smaller WebP sources and generates AVIF/WebP variants upfront, with JPEG generated only when legacy browsers request it. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
74 lines
1.7 KiB
Elixir
74 lines
1.7 KiB
Elixir
defmodule SimpleshopTheme.ImageFixtures do
|
|
@moduledoc """
|
|
Shared fixtures for image-related tests.
|
|
"""
|
|
|
|
alias SimpleshopTheme.Repo
|
|
alias SimpleshopTheme.Media.Image
|
|
|
|
@sample_jpeg File.read!("test/fixtures/sample_1200x800.jpg")
|
|
|
|
def sample_jpeg, do: @sample_jpeg
|
|
|
|
def image_fixture(attrs \\ %{}) do
|
|
{:ok, webp, w, h} = SimpleshopTheme.Images.Optimizer.to_optimized_webp(@sample_jpeg)
|
|
|
|
defaults = %{
|
|
image_type: "product",
|
|
filename: "test.jpg",
|
|
content_type: "image/webp",
|
|
file_size: byte_size(webp),
|
|
data: webp,
|
|
source_width: w,
|
|
source_height: h,
|
|
variants_status: "pending",
|
|
is_svg: false
|
|
}
|
|
|
|
%Image{}
|
|
|> Image.changeset(Map.merge(defaults, attrs))
|
|
|> Repo.insert!()
|
|
end
|
|
|
|
def svg_fixture do
|
|
svg = ~s(<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><rect/></svg>)
|
|
|
|
%Image{}
|
|
|> Image.changeset(%{
|
|
image_type: "logo",
|
|
filename: "logo.svg",
|
|
content_type: "image/svg+xml",
|
|
file_size: byte_size(svg),
|
|
data: svg,
|
|
is_svg: true,
|
|
svg_content: svg,
|
|
variants_status: "pending"
|
|
})
|
|
|> Repo.insert!()
|
|
end
|
|
|
|
def cache_path(id, width, format) do
|
|
ext =
|
|
case format do
|
|
:jpg -> "jpg"
|
|
:webp -> "webp"
|
|
:avif -> "avif"
|
|
"thumb" -> "jpg"
|
|
_ -> to_string(format)
|
|
end
|
|
|
|
filename =
|
|
case width do
|
|
"thumb" -> "#{id}-thumb.#{ext}"
|
|
_ -> "#{id}-#{width}.#{ext}"
|
|
end
|
|
|
|
Path.join(SimpleshopTheme.Images.Optimizer.cache_dir(), filename)
|
|
end
|
|
|
|
def cleanup_cache do
|
|
cache_dir = SimpleshopTheme.Images.Optimizer.cache_dir()
|
|
if File.exists?(cache_dir), do: File.rm_rf!(cache_dir)
|
|
end
|
|
end
|