Add resizing filter to make sure pictures are not too big
Closes #810 Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
f3a05929d9
commit
51cd066a14
@ -67,6 +67,7 @@ config :mobilizon, Mobilizon.Web.Upload,
|
||||
filters: [
|
||||
Mobilizon.Web.Upload.Filter.Dedupe,
|
||||
Mobilizon.Web.Upload.Filter.AnalyzeMetadata,
|
||||
Mobilizon.Web.Upload.Filter.Resize,
|
||||
Mobilizon.Web.Upload.Filter.Optimize
|
||||
],
|
||||
allow_list_mime_types: ["image/gif", "image/jpeg", "image/png", "image/webp"],
|
||||
|
42
lib/web/upload/filter/resize.ex
Normal file
42
lib/web/upload/filter/resize.ex
Normal file
@ -0,0 +1,42 @@
|
||||
defmodule Mobilizon.Web.Upload.Filter.Resize do
|
||||
@moduledoc """
|
||||
Resize the pictures if they're bigger than maximum size.
|
||||
|
||||
This filter requires `Mobilizon.Web.Upload.Filter.AnalyzeMetadata` to be performed before.
|
||||
"""
|
||||
|
||||
@behaviour Mobilizon.Web.Upload.Filter
|
||||
|
||||
@maximum_width 1_920
|
||||
@maximum_height 1_080
|
||||
|
||||
def filter(%Mobilizon.Web.Upload{
|
||||
tempfile: file,
|
||||
content_type: "image" <> _,
|
||||
width: width,
|
||||
height: height
|
||||
}) do
|
||||
file
|
||||
|> Mogrify.open()
|
||||
|> Mogrify.resize(string(limit_sizes({width, height})))
|
||||
|> Mogrify.save(in_place: true)
|
||||
|
||||
{:ok, :filtered}
|
||||
end
|
||||
|
||||
def filter(_), do: {:ok, :noop}
|
||||
|
||||
def limit_sizes({width, height}) when width > @maximum_width do
|
||||
new_height = round(@maximum_width * height / width)
|
||||
limit_sizes({@maximum_width, new_height})
|
||||
end
|
||||
|
||||
def limit_sizes({width, height}) when height > @maximum_height do
|
||||
new_width = round(@maximum_height * width / height)
|
||||
limit_sizes({new_width, @maximum_height})
|
||||
end
|
||||
|
||||
def limit_sizes({width, height}), do: {width, height}
|
||||
|
||||
defp string({width, height}), do: "#{width}x#{height}"
|
||||
end
|
@ -60,9 +60,11 @@ defmodule Mobilizon.Web.Upload do
|
||||
tempfile: String.t(),
|
||||
content_type: String.t(),
|
||||
path: String.t(),
|
||||
size: integer()
|
||||
size: integer(),
|
||||
width: integer(),
|
||||
height: integer()
|
||||
}
|
||||
defstruct [:id, :name, :tempfile, :content_type, :path, :size]
|
||||
defstruct [:id, :name, :tempfile, :content_type, :path, :size, :width, :height]
|
||||
|
||||
@spec store(source, options :: [option()]) :: {:ok, map()} | {:error, any()}
|
||||
def store(upload, opts \\ []) do
|
||||
|
20
test/web/upload/filter/resize_test.exs
Normal file
20
test/web/upload/filter/resize_test.exs
Normal file
@ -0,0 +1,20 @@
|
||||
defmodule Mobilizon.Web.Upload.Filter.ResizeTest do
|
||||
use Mobilizon.DataCase, async: true
|
||||
alias Mobilizon.Web.Upload.Filter.Resize
|
||||
|
||||
test "does not resize if dimensions are ok" do
|
||||
assert {100, 150} == Resize.limit_sizes({100, 150})
|
||||
end
|
||||
|
||||
test "does resize only width if needed" do
|
||||
assert {1_920, 960} == Resize.limit_sizes({2_000, 1_000})
|
||||
end
|
||||
|
||||
test "does resize only height if needed" do
|
||||
assert {540, 1_080} == Resize.limit_sizes({1_000, 2_000})
|
||||
end
|
||||
|
||||
test "does resize if dimentions are really big, and keeps ratio" do
|
||||
assert {724, 1080} == Resize.limit_sizes({10_050, 15_000})
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user