Packages
image
0.52.1
0.72.0
0.71.0
0.70.0
0.69.0
0.68.0
0.67.0
0.67.0-dev
retired
0.66.0
0.65.0
0.64.0
0.63.0
0.62.1
0.62.0
0.61.1
0.61.0
0.60.0
0.59.3
0.59.2
0.59.1
0.59.0
0.58.0
0.57.0
0.56.1
0.56.0
0.55.2
0.55.1
retired
0.55.0
0.54.4
0.54.3
0.54.2
0.54.1
0.54.0
0.53.0
0.52.3
0.52.2
0.52.1
0.52.0
retired
0.51.0
0.50.0
0.49.0
0.48.1
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.2
0.43.1
0.43.0
0.42.0
0.41.0
0.40.0
0.39.3
0.39.2
0.39.1
0.39.0
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.0
0.36.2
0.36.1
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.1
0.31.0
0.30.0
0.29.0
0.28.2
0.28.1
0.28.0
0.27.0
0.26.0
0.25.1
0.25.0
0.24.1
0.24.0
0.23.2
0.23.1
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
retired
0.19.0
0.18.1
0.18.0
0.17.0
0.16.0
0.15.0
0.14.4
0.14.2
0.14.1
0.14.0
retired
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.10.0-rc.0
retired
0.9.0
retired
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
An approachable image processing library primarily based upon Vix and libvips that is NIF-based, fast, multi-threaded, pipelined and has a low memory footprint.
Current section
Files
Jump to
Current section
Files
lib/image/social.ex
defmodule Image.Social do
@moduledoc """
Functions to introspect standard image sizes for
various social media platforms.
"""
alias Vix.Vips.Image, as: Vimage
@typedoc """
The social media platform image usage.
"""
@type image_usage :: atom()
@typedoc """
The known social media platforms.
"""
@type platform ::
:facebook
| :twitter
| :linkedin
| :pinterest
| :instagram
| :tumblr
| :youtube
| :snapchat
| :tiktok
# Before Version 1.0, this content will move from being a static
# list to a dynamic one that can be updated at runtime
# Facebook: https://www.facebook.com/help/125379114252045?helpref=faq_content
# https://www.socialpilot.co/blog/social-media-image-sizes
# https://blog.hootsuite.com/social-media-image-sizes-guide/
@social_sizes %{
facebook: %{
default: :post,
profile: "170x170",
cover_desktop: "820x312",
cover_mobile: "640x360",
post: "1200x630",
banner: "1200x630",
story: "1080x1920"
},
twitter: %{
profile: "400x400",
cover: "1500x500",
shared: "900x450",
stream: "440x220"
},
linkedin: %{
profile: "400x400",
cover: "1584x396",
company_logo: "400x400",
blog: "1200x627"
},
pinterest: %{
profile: "165x165",
cover: "800x450",
pin: "1080x1920",
board: "222x150"
},
instagram: %{
profile: "320x320",
cover: "1080x1920",
photo: %{
landscape: "1080x596",
portrait: "1080x1350",
square: "1080x1080"
},
thumb: "161x161",
story: "1080x1920",
carousel: %{
landscape: "1080x566",
portrait: "1080x1350",
square: "1080x1080"
}
},
tumblr: %{
profile: "128x128",
banner: "3000x1055",
post: "500x750"
},
youtube: %{
cover: "2560x1440",
profile: "800x800",
banner: "2048x1152",
thumbnail: "1280x720"
},
snapchat: %{
photo: "1080x1920",
share: "750x1334"
},
tiktok: %{
profile: "20x20",
video: "1080x1920"
}
}
@social_platforms Map.keys(@social_sizes)
@doc """
Return the map of social media image
sizes.
The returned map of maps is of a standard form:
* The first key is the platform name (ie `:twitter`)
* The second key is the image type for the platform (ie `:profile`)
* The third level is optional. But if it exists it must
have three keys: `:landscape`, `:portrait` and `:square`
The values are all of the form "WxH" where `W` is the
width in pixels and `H` is the height in pixels.
"""
def media_sizes do
@social_sizes
end
@doc """
Returns a list of known social
platforms.
### Example
"""
@spec known_platforms :: [platform()]
def known_platforms do
@social_platforms
end
@doc """
Returns the image types for the given
social platform.
### Arguments
* `platform` is any known social platform.
See `Image.Social.known_platforms/0`.
### Returns
* A list of images uses available for the
platform.
### Example
"""
@spec image_usages(platform()) :: [image_usage()]
def image_usages(platform) when platform in @social_platforms do
media_sizes()
|> Map.fetch!(platform)
|> Map.delete(:default)
|> Map.keys()
end
@doc """
Returns the default image type that an
image is resized to for a given platform
is no `:type` parameter is provided.
### Arguments
* `platform` is any known social platform.
See `Image.Social.known_platforms/0`.
### Returns
* The default image type for the platform.
### Example
"""
@spec default_image_usage(platform()) :: image_usage()
def default_image_usage(platform) when platform in @social_platforms do
media_sizes()
|> Map.fetch!(platform)
|> Map.get(:default)
end
@doc """
Resize an image for a particular social
platform and usage.
This function:
* Resizes an image to the correct dimensions, including being
image aspect aware
* Converts to the sRGB color space
* Minimises metadata (retains only Artist and Copyright)
### Arguments
* `image` is any `t:Vix.Vips.Image.t/0`
* `platform` is the name of a known social
media platform. See `Image.Social.known_platforms/0`.
* `options` is a keyword list of options.
### Options
* `:type` is the image type within the social
platform for which the image should be resized. See
`Image.Social.image_usages/1`
* All other options are passed to `Image.thumbnail!/3`.
### Returns
* `{:ok, resized_image}` or
* `{:error, reason}`
"""
@spec resize(Vimage.t(), platform(), Keyword.t()) ::
{:ok, Vimage.t()} | {:error, Image.error_message()}
def resize(image, platform, options \\ [])
def resize(%Vimage{} = image, platform, options) when platform in @social_platforms do
{usage, options} = Keyword.pop(options, :usage, :default)
options = Keyword.put_new(options, :crop, :attention)
aspect = Image.aspect(image)
platform = Map.fetch!(media_sizes(), platform)
with {:ok, size} <- get_image_size(platform, usage, aspect) do
image
|> Image.thumbnail!(size, options)
|> Image.to_colorspace!(:srgb)
|> Image.minimize_metadata()
end
end
def resize(%Vimage{} = _image, platform, _options) do
{:error, unknown_platform_error(platform)}
end
@doc """
Resize an image for a particular social
platform and usage.
This function:
* Resizes an image to the correct dimensions, including being
image orientation aware
* Converts to the sRGB color space
* Minimises metadata (retains only Artist and Copyright)
### Arguments
* `image` is any `t:Vix.Vips.Image.t/0`
* `platform` is the name of a known social
media platform. See `Image.Social.known_platforms/0`.
* `options` is a keyword list of options.
### Options
* `:type` is the image type within the social
platform for which the image should be resized. See
`Image.Social.image_usages/1`
* All other options are passed to `Image.thumbnail!/3`.
## Returns
* `resized_image` or
* Raises an exception.
"""
@spec resize!(Vimage.t(), platform(), Keyword.t()) ::
Vimage.t() | no_return
def resize!(%Vimage{} = image, platform, options \\ []) do
case resize(image, platform, options) do
{:ok, image} -> image
{:error, reason} -> raise Image.Error, reason
end
end
# ---- Helpers -----
defp get_image_size(platform, :default = type, orientation) do
default = Map.get(platform, type, {nil, type})
get_image_size(platform, default, orientation)
end
defp get_image_size(_platform, {nil, usage}, _orientation) do
{:error, unknown_usage_error(usage)}
end
defp get_image_size(platform, usage, orientation) when is_map_key(platform, usage) do
platform
|> Map.get(usage)
|> resolve_orientation(orientation)
end
defp get_image_size(_platform, usage, _orientation) do
{:error, unknown_usage_error(usage)}
end
defp resolve_orientation(size, _orientation) when is_binary(size) do
{:ok, size}
end
defp resolve_orientation(sizes, orientation) when is_map_key(sizes, orientation) do
{:ok, Map.fetch!(sizes, orientation)}
end
defp resolve_orientation(_sizes, orientation) do
{:error, unknown_orientation_error(orientation)}
end
defp unknown_platform_error(platform) do
"Unknown social platform #{inspect(platform)}"
end
defp unknown_usage_error(:default) do
"No :default usage is configured"
end
defp unknown_usage_error(usage) do
"Unknown image usage #{inspect(usage)}"
end
defp unknown_orientation_error(orientation) do
"Unknown orientation #{inspect(orientation)}"
end
end