diff options
author | Mark Felder <feld@feld.me> | 2023-11-16 17:04:47 -0500 |
---|---|---|
committer | Mark Felder <feld@feld.me> | 2023-11-17 10:26:00 -0500 |
commit | 0c6a54b37cb208e577fc9e40782bb8b820730428 (patch) | |
tree | 8a196136a5b3a699611d1360dca6c79af2bc2a67 /lib | |
parent | ce42dac331e49dd5ab8c8bca248ee11916804186 (diff) | |
download | pleroma-0c6a54b37cb208e577fc9e40782bb8b820730428.tar.gz pleroma-0c6a54b37cb208e577fc9e40782bb8b820730428.zip |
Upload.Filter.AnalyzeMetadata: Blurhash with a Rust NIF, and use Vix to retrieve image metadata
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/upload/filter/analyze_metadata.ex | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/lib/pleroma/upload/filter/analyze_metadata.ex b/lib/pleroma/upload/filter/analyze_metadata.ex index 9a76a998b..15dec5564 100644 --- a/lib/pleroma/upload/filter/analyze_metadata.ex +++ b/lib/pleroma/upload/filter/analyze_metadata.ex @@ -8,22 +8,23 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do """ require Logger + alias Vix.Vips.Image + alias Vix.Vips.Operation + @behaviour Pleroma.Upload.Filter @spec filter(Pleroma.Upload.t()) :: {:ok, :filtered, Pleroma.Upload.t()} | {:ok, :noop} | {:error, String.t()} def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _} = upload) do try do - image = - file - |> Mogrify.open() - |> Mogrify.verbose() + {:ok, image} = Image.new_from_file(file) + {width, height} = {Image.width(image), Image.height(image)} upload = upload - |> Map.put(:width, image.width) - |> Map.put(:height, image.height) - |> Map.put(:blurhash, get_blurhash(file)) + |> Map.put(:width, width) + |> Map.put(:height, height) + |> Map.put(:blurhash, get_blurhash(image)) {:ok, :filtered, upload} rescue @@ -53,7 +54,7 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do def filter(_), do: {:ok, :noop} defp get_blurhash(file) do - with {:ok, blurhash} <- :eblurhash.magick(file) do + with {:ok, blurhash} <- vips_blurhash(file) do blurhash else _ -> nil @@ -80,4 +81,23 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadata do {:error, _} = error -> error end end + + defp vips_blurhash(image = %Vix.Vips.Image{}) do + {:ok, resized_image} = Operation.thumbnail_image(image, 20) + {height, width} = {Image.height(resized_image), Image.width(resized_image)} + max = max(height, width) + {x, y} = {max(round(width * 5 / max), 1), max(round(height * 5 / max), 1)} + + {:ok, rgba} = + if Image.has_alpha?(resized_image) do + Image.to_list(resized_image) + else + Operation.bandjoin_const!(resized_image, [255]) + |> Image.to_list() + end + + rgba = List.flatten(rgba) + + Blurhash.encode(x, y, width, height, rgba) + end end |