widthxheight support
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
defmodule LabelmakerWeb.Constants do
|
defmodule LabelmakerWeb.Constants do
|
||||||
@defaults %{
|
@defaults %{
|
||||||
|
color: "black",
|
||||||
|
font: "Helvetica",
|
||||||
|
gravity: "Center",
|
||||||
|
height: "0",
|
||||||
label: "",
|
label: "",
|
||||||
link: "",
|
link: "",
|
||||||
font: "Helvetica",
|
|
||||||
color: "black",
|
|
||||||
outline: "none",
|
outline: "none",
|
||||||
size: "72"
|
size: "72",
|
||||||
|
width: "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
@preview %{
|
@preview %{
|
||||||
@@ -53,8 +56,11 @@ defmodule LabelmakerWeb.Constants do
|
|||||||
"verdana" => "Verdana"
|
"verdana" => "Verdana"
|
||||||
}
|
}
|
||||||
|
|
||||||
@max_label_length 64
|
@max_height 1024
|
||||||
@max_label_error "64-character maximum"
|
@max_width 1024
|
||||||
|
|
||||||
|
@max_label_length 1024
|
||||||
|
@max_label_error "1024-character maximum"
|
||||||
|
|
||||||
@sizes 16..128
|
@sizes 16..128
|
||||||
|> Enum.to_list()
|
|> Enum.to_list()
|
||||||
@@ -73,6 +79,8 @@ defmodule LabelmakerWeb.Constants do
|
|||||||
|> Enum.map(fn color -> color |> String.replace("-MS", "") |> String.replace("-", " ") end)
|
|> Enum.map(fn color -> color |> String.replace("-MS", "") |> String.replace("-", " ") end)
|
||||||
|
|
||||||
def font_map, do: @font_map
|
def font_map, do: @font_map
|
||||||
|
def max_height, do: @max_height
|
||||||
|
def max_width, do: @max_width
|
||||||
def max_label_length, do: @max_label_length
|
def max_label_length, do: @max_label_length
|
||||||
def max_label_error, do: @max_label_error
|
def max_label_error, do: @max_label_error
|
||||||
def outlines, do: ["none" | @colors]
|
def outlines, do: ["none" | @colors]
|
||||||
|
|||||||
@@ -16,9 +16,14 @@ defmodule LabelmakerWeb.LabelController do
|
|||||||
|
|
||||||
filename = filename <> ".png"
|
filename = filename <> ".png"
|
||||||
filepath = Path.join(@label_dir, filename)
|
filepath = Path.join(@label_dir, filename)
|
||||||
|
options = Map.put(options, :filepath, filepath)
|
||||||
|
|
||||||
unless File.exists?(filepath) do
|
unless File.exists?(filepath) do
|
||||||
generate_image(options, filepath)
|
basic_settings(options)
|
||||||
|
|> size_settings(options)
|
||||||
|
|> outline_settings(options)
|
||||||
|
|> final_settings(options)
|
||||||
|
|> generate_image()
|
||||||
end
|
end
|
||||||
|
|
||||||
conn
|
conn
|
||||||
@@ -26,36 +31,61 @@ defmodule LabelmakerWeb.LabelController do
|
|||||||
|> send_file(200, filepath)
|
|> send_file(200, filepath)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp generate_image(options, filepath) do
|
defp basic_settings(options) do
|
||||||
File.mkdir_p!(@label_dir)
|
[
|
||||||
|
|
||||||
args = [
|
|
||||||
"-background",
|
"-background",
|
||||||
"none",
|
"none",
|
||||||
"-fill",
|
"-fill",
|
||||||
options.color,
|
options.color,
|
||||||
"-pointsize",
|
|
||||||
options.size,
|
|
||||||
"-font",
|
"-font",
|
||||||
options.font,
|
options.font
|
||||||
"label:#{String.slice(options.label, 0, Constants.max_label_length())}",
|
|
||||||
"-set",
|
|
||||||
"comment",
|
|
||||||
inspect(Jason.encode!(Map.drop(options, [:link]))),
|
|
||||||
filepath
|
|
||||||
]
|
]
|
||||||
|
end
|
||||||
|
|
||||||
args =
|
defp size_settings(args, %{height: 0, width: 0} = options) do
|
||||||
if options.outline != "none" do
|
args ++
|
||||||
[
|
[
|
||||||
"-stroke",
|
"-pointsize",
|
||||||
options.outline,
|
options.size,
|
||||||
"-strokewidth",
|
"label:#{String.slice(options.label, 0, Constants.max_label_length())}"
|
||||||
"1"
|
]
|
||||||
] ++ args
|
end
|
||||||
else
|
|
||||||
args
|
defp size_settings(args, %{gravity: gravity, height: height, width: width} = options) do
|
||||||
end
|
args ++
|
||||||
|
[
|
||||||
|
"-gravity",
|
||||||
|
gravity,
|
||||||
|
"-size",
|
||||||
|
"#{width}x#{height}",
|
||||||
|
"caption:#{String.slice(options.label, 0, Constants.max_label_length())}"
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp outline_settings(args, %{outline: "none"}), do: args
|
||||||
|
|
||||||
|
defp outline_settings(args, %{outline: color}) do
|
||||||
|
args ++
|
||||||
|
[
|
||||||
|
"-stroke",
|
||||||
|
color,
|
||||||
|
"-strokewidth",
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp final_settings(args, options) do
|
||||||
|
args ++
|
||||||
|
[
|
||||||
|
"-set",
|
||||||
|
"comment",
|
||||||
|
inspect(Jason.encode!(Map.drop(options, [:filepath, :link]))),
|
||||||
|
options.filepath
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp generate_image(args) do
|
||||||
|
File.mkdir_p!(@label_dir)
|
||||||
|
|
||||||
{_, 0} = System.cmd("magick", args)
|
{_, 0} = System.cmd("magick", args)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,37 +8,33 @@ defmodule LabelmakerWeb.Tools do
|
|||||||
alias LabelmakerWeb.Constants
|
alias LabelmakerWeb.Constants
|
||||||
|
|
||||||
def process_parameters(parameters) do
|
def process_parameters(parameters) do
|
||||||
# ensure our defaults are in place to cover any missing parameters
|
parameters =
|
||||||
%{"label" => label, "size" => size} =
|
|
||||||
Constants.defaults()
|
Constants.defaults()
|
||||||
|> Map.new(fn {k, v} -> {Atom.to_string(k), v} end)
|
|> Map.new(fn {k, v} -> {Atom.to_string(k), v} end)
|
||||||
|> Map.merge(parameters)
|
|> Map.merge(parameters)
|
||||||
|
|
||||||
link = ~p"/#{label}?#{Map.take(parameters, ["color", "font", "outline", "size"])}"
|
|
||||||
line_breaks = Regex.scan(~r/#{Regex.escape("\\n")}/, label) |> length()
|
|
||||||
size = String.to_integer(size)
|
|
||||||
|
|
||||||
parameters =
|
|
||||||
parameters
|
|
||||||
|> Map.take(Constants.permitted_keys())
|
|> Map.take(Constants.permitted_keys())
|
||||||
|> Map.new(fn {k, v} -> {String.to_atom(k), v} end)
|
|> Map.new(fn {k, v} -> {String.to_atom(k), v} end)
|
||||||
|> Enum.map(fn
|
|> Enum.map(fn
|
||||||
{:font, font} ->
|
{:font, font} ->
|
||||||
{:font, Constants.font_map()[String.downcase(font)]}
|
{:font, Constants.font_map()[String.downcase(font)]}
|
||||||
|
|
||||||
|
{:height, height} ->
|
||||||
|
{:height, process_height(height, parameters)}
|
||||||
|
|
||||||
{:label, label} ->
|
{:label, label} ->
|
||||||
if String.length(label) > Constants.max_label_length(),
|
{:label, process_label(label)}
|
||||||
do: {:label, String.slice(label, 0, Constants.max_label_length() + 1)},
|
|
||||||
else: {:label, label}
|
|
||||||
|
|
||||||
{:link, _} ->
|
{:link, _} ->
|
||||||
{:link, link}
|
{:link, generate_link(parameters)}
|
||||||
|
|
||||||
{:preview_height, _} ->
|
{:preview_height, _} ->
|
||||||
{:preview_height, size + size * line_breaks}
|
{:preview_height, calculate_preview_height(parameters)}
|
||||||
|
|
||||||
{:preview_text, _} ->
|
{:preview_text, _} ->
|
||||||
{:preview_text, String.split(label, "\\n")}
|
{:preview_text, String.split(parameters.label, "\\n")}
|
||||||
|
|
||||||
|
{:width, width} ->
|
||||||
|
{:width, process_width(width, parameters)}
|
||||||
|
|
||||||
pair ->
|
pair ->
|
||||||
pair
|
pair
|
||||||
@@ -55,6 +51,51 @@ defmodule LabelmakerWeb.Tools do
|
|||||||
Map.merge(Constants.defaults(), parameters)
|
Map.merge(Constants.defaults(), parameters)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp process_height("0", parameters) do
|
||||||
|
parameters.width |> String.to_integer() |> max(0) |> min(Constants.max_height())
|
||||||
|
end
|
||||||
|
|
||||||
|
defp process_height(height, _parameters) do
|
||||||
|
height |> String.to_integer() |> max(0) |> min(Constants.max_height())
|
||||||
|
end
|
||||||
|
|
||||||
|
defp process_label(label) do
|
||||||
|
if String.length(label) > Constants.max_label_length() do
|
||||||
|
String.slice(label, 0, Constants.max_label_length())
|
||||||
|
else
|
||||||
|
label
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp generate_link(%{:height => "0", "label" => label, :width => "0"} = parameters) do
|
||||||
|
~p"/#{label}?#{Map.take(parameters, ["color", "font", "outline", "size"])}"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp generate_link(%{height: "0", width: width} = parameters),
|
||||||
|
do: generate_link(%{parameters | height: width, width: width})
|
||||||
|
|
||||||
|
defp generate_link(%{height: height, width: "0"} = parameters),
|
||||||
|
do: generate_link(%{parameters | height: height, width: height})
|
||||||
|
|
||||||
|
defp generate_link(%{"label" => label} = parameters) do
|
||||||
|
~p"/#{label}?#{Map.take(parameters, ["color", "font", "height", "outline", "width"])}"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp process_width("0", parameters) do
|
||||||
|
parameters.height |> String.to_integer() |> max(0) |> min(Constants.max_width())
|
||||||
|
end
|
||||||
|
|
||||||
|
defp process_width(width, _parameters) do
|
||||||
|
width |> String.to_integer() |> max(0) |> min(Constants.max_width())
|
||||||
|
end
|
||||||
|
|
||||||
|
defp calculate_preview_height(parameters) do
|
||||||
|
size = parameters.size |> String.to_integer()
|
||||||
|
line_breaks = Regex.scan(~r/#{Regex.escape("\\n")}/, parameters.label) |> length()
|
||||||
|
|
||||||
|
size + size * line_breaks
|
||||||
|
end
|
||||||
|
|
||||||
def outline(_, error: true), do: outline(Constants.danger(), false)
|
def outline(_, error: true), do: outline(Constants.danger(), false)
|
||||||
def outline("none", _error), do: ""
|
def outline("none", _error), do: ""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user