ExImageInfo (ExImageInfo v1.0.0)
View SourceExImageInfo is an Elixir library to parse images (binaries) and get the dimensions (size), detected mime-type and overall validity for a set of image formats. Main module to parse a binary and get if it seems to be an image (validity), the mime-type (and variant detected) and the dimensions of the image, based on a specific image format.
It has convention functions to guess the type of an image by trying the formats supported by the library.
Main features
- Check the validity of binary by providing a specific image format*.
- Guess the validity of an image*.
- Get the mime-type and variant type by providing a specific format.
- Guess the mime-type and variant type of an image.
- Get the dimensions of an image by providing a specific format.
- Guess the dimensions of an image.
*Note: both cases as a general overview (partially checked).
Formats
Supported formats (image type to be parsed as):
:bmp
:gif
:ico
:jpeg
(:jpg
alias sincev0.2.3
):jp2
:png
:pnm
:psd
:tiff
:webp
:avif
:heic
:heif
Mime-types and Variants
The image variant type is an invented string to identify the type of format recognized by this library (more specific than the mime-type).
Each mime-type can be linked to at least one variant type:
mime-type | variant type | description | since version |
---|---|---|---|
image/avif | AVIF | v1.0.0 | |
image/avif-sequence | AVIFS | v1.0.0 | |
image/bmp | BMP | ||
image/gif | GIF87a | 87a gif spec | |
image/gif | GIF89a | 89a gif spec | |
image/heic | HEIC | v1.0.0 | |
image/heic-sequence | HEICS | v1.0.0 | |
image/heif | HEIF | v1.0.0 | |
image/heif-sequence | HEIFS | v1.0.0 | |
image/x-icon | ICO | v0.2.0 | |
image/jp2 | JP2 | JPEG2000 | v0.2.0 |
image/jpeg | baseJPEG | baseline JPEG | |
image/jpeg | progJPEG | progressive JPEG | |
image/png | PNG | ||
image/x-portable-anymap | PNMpbm | Portable BitMap | v0.2.0 |
image/x-portable-anymap | PNMpgm | Portable GrayMap | v0.2.0 |
image/x-portable-anymap | PNMppm | Portable PixMap | v0.2.0 |
image/psd | PSD | ||
image/tiff | TIFFII | II variant | |
image/tiff | TIFFMM | MM variant | |
image/webp | webpVP8 | lossy | |
image/webp | webpVP8L | lossless | |
image/webp | webpVP8X | animated | v0.2.4 |
The variant type is created just to provide a bit more of information for every image format (if applicable). If version is empty, it means that it was supported since the initial release.
Formats (maybe) containing multiple images:
:ico
returns the dimensions of the largest image found.:heif
,:heic
and:avif
return the dimensions of the main image being selected (primary_box
).
The guessing functions try to detect the format of the binary by testing every available type based on its global usage and current trends (popularity, usage of image file formats):
jpeg
,png
,webp
,avif
,gif
,heic
,heif
,bmp
,ico
,tiff
,psd
,jp2
,pnm
Warnings:
- Use with caution the formats ico, jp2 and the family pnm. They are implemented without following other libraries (just reading the specs - sometimes working with old drafts like jp2).
- ISOBMFF format (heif, heic and avif) is the most complex format being supported, with most parts being implemented following the specs and testing against binary streams manually produced. Please, use with caution and report any issue found.
Contributions: you can support this library by providing more tests, image fixtures (like image/heic-sequence
),
increasing code coverage or extending support for other variants.
Summary
Types
Supported image format types.
Functions
Gets the mime-type, variant-type and dimensions (width, height) for the given image binary
(guessed version of ExImageInfo.info/2
).
Gets the mime-type, variant-type and dimensions (width, height) for the given image format and binary.
Detects the image format that seems to be the given binary (guessed version of ExImageInfo.seems?/2
).
Detects if the given binary seems to be in the given image format.
Gets the mime-type and variant type for the given image binary (guessed version of ExImageInfo.type/2
).
Gets the mime-type and variant type for the given image format and binary.
Types
Functions
@spec info(binary()) :: {mimetype :: String.t(), width :: integer(), height :: integer(), variant :: String.t()} | nil
Gets the mime-type, variant-type and dimensions (width, height) for the given image binary
(guessed version of ExImageInfo.info/2
).
Possible Mime-types and Variants to be returned.
Returns a 4-item tuple with the mime-type, width, height and the variant type when the binary matches, nil
otherwise.
Examples
iex> ExImageInfo.info <<0x38425053::size(32)>>
nil
iex> ExImageInfo.info <<0x38425053::size(32), 0::size(80), 10::size(32), 12::size(32)>>
{"image/psd", 12, 10, "PSD"}
Usually it is used as:
ExImageInfo.info File.read!("path/to/image.unknown")
# {"image/tiff", 128, 256, "TIFFMM"}
webp_full_binary |> ExImageInfo.info
# {"image/webp", 20, 100, "webpVP8"}
@spec info(binary(), format :: image_format()) :: {mimetype :: String.t(), width :: integer(), height :: integer(), variant :: String.t()} | nil
Gets the mime-type, variant-type and dimensions (width, height) for the given image format and binary.
Possible Mime-types and Variants to be returned.
Valid formats to be used.
Returns a 4-item tuple with the mime-type, width, height and the variant type when the binary matches, nil
otherwise.
Examples
89 50 4E 47 0D 0A 1A 0A
are the first 8 bytes in the PNG
signature (PNG\r\n0x1A\n
).
iex> ExImageInfo.info <<0x89504E470D0A1A0A::size(64)>>, :png
nil
iex> ExImageInfo.info <<"RIFF", 0::size(32), "WEBPVP8L", 0::size(32), 0x2F7AC07100358683B68D::size(80)>>, :webp
{"image/webp", 123, 456, "webpVP8L"}
The signature part of a png it is now enough to get the type (it check also the IHDR field, just before the width and height).
Usually it is used as:
ExImageInfo.info File.read!("path/to/image.gif"), :gif
# {"image/gif", 1920, 1080, "GIF87a"}
maybe_png_binary |> ExImageInfo.info :png
# nil
If a binary is malformed, it returns nil
, even if other calls like type
or seems?
return valid types.
{ExImageInfo.type(malformed_heif_binary, :heif), ExImageInfo.info(malformed_heif_binary, :heif)}
# {{"image/heif", "HEIF"}, nil}
@spec seems?(binary()) :: image_format() | nil
Detects the image format that seems to be the given binary (guessed version of ExImageInfo.seems?/2
).
Returns the valid format (atom) if it matches, nil
otherwise.
Examples
38 42 50 53
are the first 4 bytes in the PSD
signature (8BPS
).
iex> ExImageInfo.seems? <<0x38425053::size(32)>>
:psd
iex> ExImageInfo.seems? <<0x384250::size(24)>>
nil
ExImageInfo.seems?/2
and ExImageInfo.seems?/1
does not necessarily needs a real image
(as it is shown in the previous example) because it just checks the signature of every file format.
Usually it is used as:
ExImageInfo.seems? File.read!("path/to/image.unknown")
# :tiff
webp_full_binary |> ExImageInfo.seems?
# :webp
@spec seems?(binary(), format :: image_format()) :: boolean()
Detects if the given binary seems to be in the given image format.
Valid formats to be used.
Returns true
if the binary seems to be the format specified, false
if it
is not, and nil
if the type is unsupported.
Examples
89 50 4E 47 0D 0A 1A 0A
are the first 8 bytes in the PNG
signature (PNG\r\n0x1A\n
).
iex> ExImageInfo.seems? <<0x89504E470D0A1A0A::size(64)>>, :png
true
iex> ExImageInfo.seems? <<0x89504E470D0A1A0A::size(64)>>, :webp
false
ExImageInfo.seems?/2
and ExImageInfo.seems?/1
does not necessarily needs a real image
(as it is shown in the previous example) because it just checks the signature of every file format.
Usually it is used as:
ExImageInfo.seems? File.read!("path/to/image.gif"), :gif
# true
maybe_png_binary |> ExImageInfo.seems? :png
# false
Gets the mime-type and variant type for the given image binary (guessed version of ExImageInfo.type/2
).
Possible Mime-types and Variants to be returned.
Returns a 2-item tuple with the mime-type and the variant type when the binary matches, nil
otherwise.
Examples
iex> ExImageInfo.type <<0x38425053::size(32)>>
{"image/psd", "PSD"}
iex> ExImageInfo.type <<0x384250::size(24)>>
nil
Usually it is used as:
ExImageInfo.type File.read!("path/to/image.unknown")
# {"image/tiff", "TIFFMM"}
webp_full_binary |> ExImageInfo.type
# {"image/webp", "webpVP8"}
@spec type(binary(), format :: image_format()) :: {mimetype :: String.t(), variant :: String.t()} | nil
Gets the mime-type and variant type for the given image format and binary.
Possible Mime-types and Variants to be returned.
Valid formats to be used.
Returns a 2-item tuple with the mime-type and the variant type when the binary matches, nil
otherwise.
Examples
89 50 4E 47 0D 0A 1A 0A
are the first 8 bytes in the PNG
signature (PNG\r\n0x1A\n
).
iex> ExImageInfo.type <<0x89504E470D0A1A0A::size(64)>>, :png
nil
iex> ExImageInfo.type <<"RIFF", 0::size(32), "WEBPVP8L", 0::size(32), 0x2F7AC07100358683B68D::size(80)>>, :webp
{"image/webp", "webpVP8L"}
The signature part of a png it is now enough to get the type (it check also the IHDR field, just before the width and height).
Usually it is used as:
ExImageInfo.type File.read!("path/to/image.gif"), :gif
# {"image/gif", "GIF87a"}
maybe_png_binary |> ExImageInfo.type :png
# nil