Skip to content

Instantly share code, notes, and snippets.

@teamon
Created September 9, 2016 21:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teamon/725048bf55932c0a3f5f50b4848105f3 to your computer and use it in GitHub Desktop.
Save teamon/725048bf55932c0a3f5f50b4848105f3 to your computer and use it in GitHub Desktop.
Quickly create avatar image from user name (initials)
# Much simplified version based on https://github.com/zhangsoledad/alchemic_avatar
# Avatar.generate/2 returns a Plug.Upload that can be passed directly
# into Ecto.Changeset (as for example fallback image)
defmodule Avatar do
@defaults [
size: 300,
font_path: Application.app_dir(:my_app, "priv/fonts/Roboto.ttf"),
font_size: 40,
font_weight: 500,
font_color: {255,0,0}, # {r,g,b}
background_color: {0,255,0} # {r,g,b}
]
def generate(name, opts \\ []) do
text = initials(name)
{:ok, path} = Plug.Upload.random_file("avatar") # generate random text file
convert(path, text, opts)
%Plug.Upload{
path: path,
filename: "avatar.png",
content_type: "image/png"
}
end
defp convert(path, text, opts) do
size = Keyword.get(opts, :size, @defaults[:size])
font_path = Keyword.get(opts, :font_path, @defaults[:font_path])
font_size = Keyword.get(opts, :font_size, @defaults[:font_size])
font_weight = Keyword.get(opts, :font_weight, @defaults[:font_weight])
font_color = Keyword.get(opts, :font_color, @defaults[:font_color])
bg_color = Keyword.get(opts, :background_color, @defaults[:background_color])
# this is taken directly from on https://github.com/zhangsoledad/alchemic_avatar
# see imagemagic docs if you need to tweak something
System.cmd "convert", [
"-size", "#{size}x#{size}",
"xc:#{rgb(bg_color)}",
"-font", font_path,
"-pointsize", to_string(font_size),
"-weight", to_string(font_weight),
"-fill", rgb(font_color),
"-gravity", "Center",
"-annotate", "-0+5", text,
"png:#{path}"
]
end
# very very very naive initials, do not use this!
# please remember about different names in different parts of the world
# see https://www.w3.org/International/questions/qa-personal-names for some examples
defp initials(name) do
name
|> to_string
|> String.split(~r/\s+/, parts: 2)
|> Enum.map(&String.slice(&1, 0, 1))
|> Enum.map(&String.upcase/1)
|> Enum.join("")
end
defp rgb({r,g,b}), do: "rgb(#{r},#{g},#{b})"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment