philomena/lib/philomena_media/processors/png.ex

92 lines
2.3 KiB
Elixir

defmodule PhilomenaMedia.Processors.Png do
@moduledoc false
alias PhilomenaMedia.Intensities
alias PhilomenaMedia.Analyzers.Result
alias PhilomenaMedia.Processors.Processor
alias PhilomenaMedia.Processors
@behaviour Processor
@spec versions(Processors.version_list()) :: [Processors.version_filename()]
def versions(sizes) do
Enum.map(sizes, fn {name, _} -> "#{name}.png" end)
end
@spec process(Result.t(), Path.t(), Processors.version_list()) :: Processors.edit_script()
def process(analysis, file, versions) do
animated? = analysis.animated?
{:ok, intensities} = Intensities.file(file)
scaled = Enum.flat_map(versions, &scale(file, animated?, &1))
[
intensities: intensities,
thumbnails: scaled
]
end
@spec post_process(Result.t(), Path.t()) :: Processors.edit_script()
def post_process(analysis, file) do
if analysis.animated? do
# libpng has trouble with animations, so skip optimization
[]
else
[replace_original: optimize(file)]
end
end
@spec intensities(Result.t(), Path.t()) :: Intensities.t()
def intensities(_analysis, file) do
{:ok, intensities} = Intensities.file(file)
intensities
end
# Sobelow misidentifies removing the .bak file
# sobelow_skip ["Traversal.FileModule"]
defp optimize(file) do
optimized = Briefly.create!(extname: ".png")
{_output, 0} =
System.cmd("optipng", ["-fix", "-i0", "-o2", "-quiet", "-clobber", file, "-out", optimized])
# Remove useless .bak file
File.rm(optimized <> ".bak")
optimized
end
defp scale(file, animated?, {thumb_name, {width, height}}) do
scaled = Briefly.create!(extname: ".png")
scale_filter =
"scale=w=#{width}:h=#{height}:force_original_aspect_ratio=decrease,format=rgb32"
{_output, 0} =
cond do
animated? ->
System.cmd("ffmpeg", [
"-loglevel",
"0",
"-y",
"-i",
file,
"-plays",
"0",
"-vf",
scale_filter,
"-f",
"apng",
scaled
])
true ->
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", file, "-vf", scale_filter, scaled])
end
System.cmd("optipng", ["-i0", "-o1", "-quiet", "-clobber", scaled])
[{:copy, scaled, "#{thumb_name}.png"}]
end
end