From 481b6ac0d5c610e840fc4b88a357efa28f510ab8 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Thu, 10 Nov 2022 11:07:49 -0500 Subject: [PATCH] Add Pleroma.Upload.Filter.HeifToJpeg based on vips --- CHANGELOG.md | 1 + lib/pleroma/upload/filter/heif_to_jpeg.ex | 36 +++++++++++++++++ test/fixtures/image.heic | Bin 0 -> 41465 bytes .../upload/filter/heif_to_jpeg_test.exs | 38 ++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 lib/pleroma/upload/filter/heif_to_jpeg.ex create mode 100644 test/fixtures/image.heic create mode 100644 test/pleroma/upload/filter/heif_to_jpeg_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index 394eb5179..7ced3b678 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -150,6 +150,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Added move account API - Enable remote users to interact with posts - Possibility to discover users like `user@example.org`, while Pleroma is working on `pleroma.example.org`. Additional configuration required. +- Added Pleroma.Upload.Filter.HeifToJpeg to automate converting .heic files from Apple devices to JPEGs which can be viewed in browsers. ### Fixed - Subscription(Bell) Notifications: Don't create from Pipeline Ingested replies diff --git a/lib/pleroma/upload/filter/heif_to_jpeg.ex b/lib/pleroma/upload/filter/heif_to_jpeg.ex new file mode 100644 index 000000000..a2095ba01 --- /dev/null +++ b/lib/pleroma/upload/filter/heif_to_jpeg.ex @@ -0,0 +1,36 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Upload.Filter.HeifToJpeg do + @behaviour Pleroma.Upload.Filter + alias Pleroma.Upload + alias Vix.Vips.Operation + + @type conversion :: action :: String.t() | {action :: String.t(), opts :: String.t()} + @type conversions :: conversion() | [conversion()] + + @spec filter(Pleroma.Upload.t()) :: {:ok, :atom} | {:error, String.t()} + def filter(%Pleroma.Upload{content_type: "image/avif"} = upload), do: apply_filter(upload) + def filter(%Pleroma.Upload{content_type: "image/heic"} = upload), do: apply_filter(upload) + def filter(%Pleroma.Upload{content_type: "image/heif"} = upload), do: apply_filter(upload) + + def filter(_), do: {:ok, :noop} + + defp apply_filter(%Pleroma.Upload{name: name, path: path, tempfile: tempfile} = upload) do + ext = String.split(path, ".") |> List.last() + + try do + name = name |> String.replace_suffix(ext, "jpg") + path = path |> String.replace_suffix(ext, "jpg") + {:ok, {vixdata, _vixflags}} = Operation.heifload(tempfile) + {:ok, jpegdata} = Operation.jpegsave_buffer(vixdata) + :ok = File.write(tempfile, jpegdata) + + {:ok, :filtered, %Upload{upload | name: name, path: path, content_type: "image/jpeg"}} + rescue + e in ErlangError -> + {:error, "#{__MODULE__}: #{inspect(e)}"} + end + end +end diff --git a/test/fixtures/image.heic b/test/fixtures/image.heic new file mode 100644 index 0000000000000000000000000000000000000000..efd119a0ea5f9c59d225e2f1ba7269bfe1802d0b GIT binary patch literal 41465 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𝔫oF3jt+&)oY$;m6 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 JuE~EV$w1k)iqQZ7 literal 0 HcmV?d00001 diff --git a/test/pleroma/upload/filter/heif_to_jpeg_test.exs b/test/pleroma/upload/filter/heif_to_jpeg_test.exs new file mode 100644 index 000000000..7627d18ce --- /dev/null +++ b/test/pleroma/upload/filter/heif_to_jpeg_test.exs @@ -0,0 +1,38 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Upload.Filter.HeifToJpegTest do + use Pleroma.DataCase, async: true + alias Pleroma.Upload.Filter + + test "apply HeicToJpeg filter" do + File.cp!( + "test/fixtures/image.heic", + "test/fixtures/heictmp" + ) + + upload = %Pleroma.Upload{ + name: "image.heic", + content_type: "image/heic", + path: Path.absname("test/fixtures/image.heic"), + tempfile: Path.absname("test/fixtures/heictmp") + } + + {:ok, :filtered, result} = Filter.HeifToJpeg.filter(upload) + + assert result.content_type == "image/jpeg" + assert result.name == "image.jpg" + assert String.ends_with?(result.path, "jpg") + + assert {:ok, + %Majic.Result{ + content: + "JPEG image data, JFIF standard 1.02, resolution (DPI), density 96x96, segment length 16, progressive, precision 8, 1024x768, components 3", + encoding: "binary", + mime_type: "image/jpeg" + }} == Majic.perform(result.path, pool: Pleroma.MajicPool) + + on_exit(fn -> File.rm!("test/fixtures/heictmp") end) + end +end