2024-06-02 00:15:09 -04:00
|
|
|
defmodule PhilomenaMedia.Processors.Png do
|
|
|
|
@moduledoc false
|
2019-11-25 19:06:40 -05:00
|
|
|
|
2024-06-02 00:15:09 -04:00
|
|
|
alias PhilomenaMedia.Intensities
|
|
|
|
alias PhilomenaMedia.Analyzers.Result
|
|
|
|
alias PhilomenaMedia.Processors.Processor
|
|
|
|
alias PhilomenaMedia.Processors
|
|
|
|
|
|
|
|
@behaviour Processor
|
|
|
|
|
|
|
|
@spec versions(Processors.version_list()) :: [Processors.version_filename()]
|
2022-02-07 22:12:40 -05:00
|
|
|
def versions(sizes) do
|
|
|
|
Enum.map(sizes, fn {name, _} -> "#{name}.png" end)
|
|
|
|
end
|
|
|
|
|
2024-06-02 00:15:09 -04:00
|
|
|
@spec process(Result.t(), Path.t(), Processors.version_list()) :: Processors.edit_script()
|
2019-11-25 21:57:47 -05:00
|
|
|
def process(analysis, file, versions) do
|
2020-07-06 14:10:35 -04:00
|
|
|
animated? = analysis.animated?
|
2019-11-25 19:06:40 -05:00
|
|
|
|
2019-11-25 21:57:47 -05:00
|
|
|
{:ok, intensities} = Intensities.file(file)
|
|
|
|
|
2022-02-07 22:30:39 -05:00
|
|
|
scaled = Enum.flat_map(versions, &scale(file, animated?, &1))
|
2019-11-25 19:06:40 -05:00
|
|
|
|
2024-06-02 00:15:09 -04:00
|
|
|
[
|
2019-11-25 21:57:47 -05:00
|
|
|
intensities: intensities,
|
|
|
|
thumbnails: scaled
|
2024-06-02 00:15:09 -04:00
|
|
|
]
|
2019-11-25 19:06:40 -05:00
|
|
|
end
|
|
|
|
|
2024-06-02 00:15:09 -04:00
|
|
|
@spec post_process(Result.t(), Path.t()) :: Processors.edit_script()
|
2021-04-07 15:16:43 -04:00
|
|
|
def post_process(analysis, file) do
|
|
|
|
if analysis.animated? do
|
|
|
|
# libpng has trouble with animations, so skip optimization
|
2024-06-02 00:15:09 -04:00
|
|
|
[]
|
2021-04-07 15:16:43 -04:00
|
|
|
else
|
2024-06-02 00:15:09 -04:00
|
|
|
[replace_original: optimize(file)]
|
2021-04-07 15:16:43 -04:00
|
|
|
end
|
2019-11-25 19:06:40 -05:00
|
|
|
end
|
|
|
|
|
2024-06-02 00:15:09 -04:00
|
|
|
@spec intensities(Result.t(), Path.t()) :: Intensities.t()
|
2019-11-28 19:11:05 -05:00
|
|
|
def intensities(_analysis, file) do
|
|
|
|
{:ok, intensities} = Intensities.file(file)
|
|
|
|
intensities
|
|
|
|
end
|
|
|
|
|
2021-04-01 12:49:41 -04:00
|
|
|
# Sobelow misidentifies removing the .bak file
|
|
|
|
# sobelow_skip ["Traversal.FileModule"]
|
2019-11-25 21:57:47 -05:00
|
|
|
defp optimize(file) do
|
2019-11-25 19:06:40 -05:00
|
|
|
optimized = Briefly.create!(extname: ".png")
|
|
|
|
|
|
|
|
{_output, 0} =
|
2019-11-26 20:45:57 -05:00
|
|
|
System.cmd("optipng", ["-fix", "-i0", "-o2", "-quiet", "-clobber", file, "-out", optimized])
|
2020-01-03 11:54:05 -05:00
|
|
|
|
|
|
|
# Remove useless .bak file
|
|
|
|
File.rm(optimized <> ".bak")
|
|
|
|
|
2019-11-25 21:57:47 -05:00
|
|
|
optimized
|
|
|
|
end
|
|
|
|
|
2022-02-07 22:30:39 -05:00
|
|
|
defp scale(file, animated?, {thumb_name, {width, height}}) do
|
2019-11-25 19:06:40 -05:00
|
|
|
scaled = Briefly.create!(extname: ".png")
|
2020-01-10 23:20:19 -05:00
|
|
|
|
|
|
|
scale_filter =
|
|
|
|
"scale=w=#{width}:h=#{height}:force_original_aspect_ratio=decrease,format=rgb32"
|
2019-11-25 19:06:40 -05:00
|
|
|
|
|
|
|
{_output, 0} =
|
2020-07-06 14:10:35 -04:00
|
|
|
cond do
|
|
|
|
animated? ->
|
2020-07-06 14:12:18 -04:00
|
|
|
System.cmd("ffmpeg", [
|
|
|
|
"-loglevel",
|
|
|
|
"0",
|
|
|
|
"-y",
|
|
|
|
"-i",
|
|
|
|
file,
|
|
|
|
"-plays",
|
|
|
|
"0",
|
|
|
|
"-vf",
|
|
|
|
scale_filter,
|
|
|
|
"-f",
|
|
|
|
"apng",
|
|
|
|
scaled
|
|
|
|
])
|
2020-01-10 23:20:19 -05:00
|
|
|
|
2020-07-06 14:10:35 -04:00
|
|
|
true ->
|
|
|
|
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", file, "-vf", scale_filter, scaled])
|
|
|
|
end
|
|
|
|
|
|
|
|
System.cmd("optipng", ["-i0", "-o1", "-quiet", "-clobber", scaled])
|
2019-11-25 19:06:40 -05:00
|
|
|
|
2022-02-07 22:30:39 -05:00
|
|
|
[{:copy, scaled, "#{thumb_name}.png"}]
|
2019-11-25 19:06:40 -05:00
|
|
|
end
|
2019-12-22 09:19:43 -05:00
|
|
|
end
|