philomena/lib/philomena/processors/jpeg.ex

89 lines
2.2 KiB
Elixir
Raw Normal View History

2019-11-25 19:06:40 -05:00
defmodule Philomena.Processors.Jpeg do
2019-11-25 21:57:47 -05:00
alias Philomena.Intensities
2019-11-25 19:06:40 -05:00
2019-11-25 21:57:47 -05:00
def process(analysis, file, versions) do
dimensions = analysis.dimensions
stripped = optimize(strip(file))
2019-11-25 19:06:40 -05:00
2019-11-25 21:57:47 -05:00
{:ok, intensities} = Intensities.file(stripped)
scaled = Enum.flat_map(versions, &scale_if_smaller(stripped, dimensions, &1))
%{
replace_original: stripped,
intensities: intensities,
thumbnails: scaled
}
2019-11-25 19:06:40 -05:00
end
2019-11-25 21:57:47 -05:00
def post_process(_analysis, _file), do: %{}
2019-11-28 19:11:05 -05:00
def intensities(_analysis, file) do
{:ok, intensities} = Intensities.file(file)
intensities
end
2019-11-25 21:57:47 -05:00
defp strip(file) do
2019-11-25 19:06:40 -05:00
stripped = Briefly.create!(extname: ".jpg")
# ImageMagick always reencodes the image, resulting in quality loss, so
# be more clever
case System.cmd("identify", ["-format", "%[orientation]", file]) do
{"Undefined", 0} ->
# Strip EXIF without touching orientation
{_output, 0} = System.cmd("jpegtran", ["-copy", "none", "-outfile", stripped, file])
{_output, 0} ->
# Strip EXIF and reorient image
{_output, 0} = System.cmd("convert", [file, "-auto-orient", "-strip", stripped])
end
2019-11-25 21:57:47 -05:00
stripped
end
2019-11-25 19:06:40 -05:00
2019-11-25 21:57:47 -05:00
defp optimize(file) do
optimized = Briefly.create!(extname: ".jpg")
2020-01-10 23:20:19 -05:00
{_output, 0} = System.cmd("jpegtran", ["-optimize", "-outfile", optimized, file])
2019-11-25 19:06:40 -05:00
2019-11-25 21:57:47 -05:00
optimized
2019-11-25 19:06:40 -05:00
end
2019-11-25 21:57:47 -05:00
defp scale_if_smaller(_file, _dimensions, {:full, _target_dim}) do
[{:symlink_original, "full.jpg"}]
2019-11-25 19:06:40 -05:00
end
2019-11-25 21:57:47 -05:00
defp scale_if_smaller(file, {width, height}, {thumb_name, {target_width, target_height}}) do
if width > target_width or height > target_height do
scaled = scale(file, {target_width, target_height})
2019-11-25 19:06:40 -05:00
2019-11-25 21:57:47 -05:00
[{:copy, scaled, "#{thumb_name}.jpg"}]
else
[{:symlink_original, "#{thumb_name}.jpg"}]
end
2019-11-25 19:06:40 -05:00
end
2019-11-25 21:57:47 -05:00
defp scale(file, {width, height}) do
2019-11-25 19:06:40 -05:00
scaled = Briefly.create!(extname: ".jpg")
scale_filter = "scale=w=#{width}:h=#{height}:force_original_aspect_ratio=decrease"
{_output, 0} =
2020-04-29 17:12:40 +02:00
System.cmd("ffmpeg", [
"-loglevel",
"0",
"-y",
"-i",
file,
"-vf",
scale_filter,
"-q:v",
"1",
scaled
])
2020-01-10 23:20:19 -05:00
{_output, 0} = System.cmd("jpegtran", ["-optimize", "-outfile", scaled, scaled])
2019-11-25 19:06:40 -05:00
2019-11-25 21:57:47 -05:00
scaled
2019-11-25 19:06:40 -05:00
end
2020-01-10 23:20:19 -05:00
end