From f1f588fd5271c0b3bf09df002a83dbb57c42bae0 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Thu, 14 May 2020 20:18:31 +0300 Subject: [PATCH] [#2497] Added support for :eimp for image resizing. --- config/config.exs | 4 +- .../web/media_proxy/media_proxy_controller.ex | 64 +++++++++++++++---- mix.exs | 2 +- 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/config/config.exs b/config/config.exs index 0f92b1ef9..e9403c7c8 100644 --- a/config/config.exs +++ b/config/config.exs @@ -393,7 +393,9 @@ # Note: media preview proxy depends on media proxy to be enabled config :pleroma, :media_preview_proxy, enabled: false, - limit_dimensions: "400x200", + enable_eimp: true, + thumbnail_max_width: 400, + thumbnail_max_height: 200, proxy_opts: [ head_request_max_read_duration: 5_000, max_read_duration: 10_000 diff --git a/lib/pleroma/web/media_proxy/media_proxy_controller.ex b/lib/pleroma/web/media_proxy/media_proxy_controller.ex index 157365e08..8d8d073e9 100644 --- a/lib/pleroma/web/media_proxy/media_proxy_controller.ex +++ b/lib/pleroma/web/media_proxy/media_proxy_controller.ex @@ -62,24 +62,64 @@ defp handle_preview(conn, url) do end end + defp thumbnail_max_dimensions(params) do + config = Config.get([:media_preview_proxy], []) + + thumbnail_max_width = + if w = params["thumbnail_max_width"] do + String.to_integer(w) + else + Keyword.fetch!(config, :thumbnail_max_width) + end + + thumbnail_max_height = + if h = params["thumbnail_max_height"] do + String.to_integer(h) + else + Keyword.fetch!(config, :thumbnail_max_height) + end + + {thumbnail_max_width, thumbnail_max_height} + end + + defp thumbnail_binary(url, body, params) do + {thumbnail_max_width, thumbnail_max_height} = thumbnail_max_dimensions(params) + + with true <- Config.get([:media_preview_proxy, :enable_eimp]), + {:ok, [type: image_type, width: source_width, height: source_height]} <- + :eimp.identify(body), + scale_factor <- + Enum.max([source_width / thumbnail_max_width, source_height / thumbnail_max_height]), + {:ok, thumbnail_binary} = + :eimp.convert(body, image_type, [ + {:scale, {round(source_width / scale_factor), round(source_height / scale_factor)}} + ]) do + {:ok, thumbnail_binary} + else + _ -> + mogrify_dimensions = "#{thumbnail_max_width}x#{thumbnail_max_height}" + + with {:ok, path} <- MogrifyHelper.store_as_temporary_file(url, body), + %Mogrify.Image{} <- + MogrifyHelper.in_place_resize_to_limit(path, mogrify_dimensions), + {:ok, thumbnail_binary} <- File.read(path), + _ <- File.rm(path) do + {:ok, thumbnail_binary} + else + _ -> :error + end + end + end + defp handle_preview("image/" <> _ = content_type, %{params: params} = conn, url) do - with {:ok, %{status: status, body: body}} when status in 200..299 <- + with {:ok, %{status: status, body: image_contents}} when status in 200..299 <- url |> MediaProxy.url() |> Tesla.get(opts: [adapter: [timeout: preview_timeout()]]), - {:ok, path} <- MogrifyHelper.store_as_temporary_file(url, body), - resize_dimensions <- - Map.get( - params, - "limit_dimensions", - Config.get([:media_preview_proxy, :limit_dimensions]) - ), - %Mogrify.Image{} <- MogrifyHelper.in_place_resize_to_limit(path, resize_dimensions), - {:ok, image_binary} <- File.read(path), - _ <- File.rm(path) do + {:ok, thumbnail_binary} <- thumbnail_binary(url, image_contents, params) do conn |> put_resp_header("content-type", content_type) - |> send_resp(200, image_binary) + |> send_resp(200, thumbnail_binary) else {_, %{status: _}} -> send_resp(conn, :failed_dependency, "Can't fetch the image.") diff --git a/mix.exs b/mix.exs index a9c4ad2e3..332febe48 100644 --- a/mix.exs +++ b/mix.exs @@ -139,7 +139,7 @@ defp deps do github: "ninenines/gun", ref: "e1a69b36b180a574c0ac314ced9613fdd52312cc", override: true}, {:jason, "~> 1.0"}, {:mogrify, "~> 0.6.1"}, - {:eimp, ">= 0.0.0"}, + {:eimp, "~> 1.0.14"}, {:ex_aws, "~> 2.1"}, {:ex_aws_s3, "~> 2.0"}, {:sweet_xml, "~> 0.6.6"},