Support PNG previews to preserve alpha channels
authorMark Felder <feld@FreeBSD.org>
Sun, 30 Aug 2020 14:17:24 +0000 (09:17 -0500)
committerMark Felder <feld@FreeBSD.org>
Sun, 30 Aug 2020 14:17:24 +0000 (09:17 -0500)
lib/pleroma/helpers/media_helper.ex
lib/pleroma/web/media_proxy/media_proxy_controller.ex

index 5ac75b326b146fca0a6ccd3b65611577547bd971..d8a6db4e12b3fd546e52109d873ee140aa3b82cf 100644 (file)
@@ -23,6 +23,23 @@ defmodule Pleroma.Helpers.MediaHelper do
     end
   end
 
+  defp prepare_image_resize_args(
+         %{max_width: max_width, max_height: max_height, format: "png"} = options
+       ) do
+    quality = options[:quality] || 85
+    resize = Enum.join([max_width, "x", max_height, ">"])
+
+    args = [
+      "-resize",
+      resize,
+      "-quality",
+      to_string(quality),
+      "png:-"
+    ]
+
+    {:ok, args}
+  end
+
   defp prepare_image_resize_args(%{max_width: max_width, max_height: max_height} = options) do
     quality = options[:quality] || 85
     resize = Enum.join([max_width, "x", max_height, ">"])
index 411dc95d08a7d60eede624d5f63f5b730348b57b..94fae6cac571f7c1de9adddde1b9374ab695cf8e 100644 (file)
@@ -76,8 +76,12 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
     redirect(conn, external: mediaproxy_url)
   end
 
+  defp handle_preview("image/png" <> _ = _content_type, conn, url) do
+    handle_png_preview(conn, url)
+  end
+
   defp handle_preview("image/" <> _ = _content_type, conn, url) do
-    handle_image_preview(conn, url)
+    handle_jpeg_preview(conn, url)
   end
 
   defp handle_preview("video/" <> _ = _content_type, conn, url) do
@@ -88,7 +92,31 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
     send_resp(conn, :unprocessable_entity, "Unsupported content type: #{content_type}.")
   end
 
-  defp handle_image_preview(%{params: params} = conn, url) do
+  defp handle_png_preview(%{params: params} = conn, url) do
+    quality = Config.get!([:media_preview_proxy, :image_quality])
+
+    with {thumbnail_max_width, thumbnail_max_height} <- thumbnail_max_dimensions(params),
+         {:ok, thumbnail_binary} <-
+           MediaHelper.image_resize(
+             url,
+             %{
+               max_width: thumbnail_max_width,
+               max_height: thumbnail_max_height,
+               quality: quality,
+               format: "png"
+             }
+           ) do
+      conn
+      |> put_resp_header("content-type", "image/png")
+      |> put_resp_header("content-disposition", "inline; filename=\"preview.png\"")
+      |> send_resp(200, thumbnail_binary)
+    else
+      _ ->
+        send_resp(conn, :failed_dependency, "Can't handle preview.")
+    end
+  end
+
+  defp handle_jpeg_preview(%{params: params} = conn, url) do
     quality = Config.get!([:media_preview_proxy, :image_quality])
 
     with {thumbnail_max_width, thumbnail_max_height} <- thumbnail_max_dimensions(params),