Packages
kino
0.10.0
0.19.0
0.18.0
0.17.0
0.16.1
0.16.0
0.15.3
0.15.2
0.15.1
0.15.0
0.14.2
0.14.1
0.14.0
0.13.2
0.13.1
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.0
0.6.2
0.6.1
0.6.0
retired
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
Interactive widgets for Livebook
Current section
Files
Jump to
Current section
Files
lib/kino/image.ex
defmodule Kino.Image do
@moduledoc """
A kino for rendering a binary image.
This is just a meta-struct that implements the `Kino.Render`
protocol, so that it gets rendered as the underlying image.
## Examples
content = File.read!("/path/to/image.jpeg")
Kino.Image.new(content, "image/jpeg")
"""
@enforce_keys [:content, :mime_type]
defstruct [:content, :mime_type]
@opaque t :: %__MODULE__{
content: binary(),
mime_type: mime_type()
}
@type mime_type :: binary()
@type common_image_type :: :jpeg | :jpg | :png | :gif | :svg | :pixel
@doc """
Creates a new kino displaying the given binary image.
The given type be either `:jpeg`/`:jpg`, `:png`, `:gif`, `:svg`, `:pixel`
or a string with image MIME type.
Note that a special `:pixel` format is supported, see `t:Kino.Output.image/0`
for the specification.
"""
@spec new(binary(), common_image_type() | mime_type()) :: t()
def new(content, type) do
%__MODULE__{content: content, mime_type: mime_type!(type)}
end
defp mime_type!(:jpeg), do: "image/jpeg"
defp mime_type!(:jpg), do: "image/jpeg"
defp mime_type!(:png), do: "image/png"
defp mime_type!(:gif), do: "image/gif"
defp mime_type!(:svg), do: "image/svg+xml"
defp mime_type!(:pixel), do: "image/x-pixel"
defp mime_type!("image/" <> _ = mime_type), do: mime_type
defp mime_type!(other) do
raise ArgumentError,
"expected image type to be either :jpeg, :png, :gif, :svg, :pixel or an image MIME type string, got: #{inspect(other)}"
end
@compile {:no_warn_undefined, Nx}
@doc """
Creates a new kino similarly to `new/2` from a compatible term.
Currently the supported terms are:
* `Nx.Tensor` in HWC order
"""
@spec new(struct()) :: t()
def new(tensor) when is_struct(tensor, Nx.Tensor) do
type = Nx.type(tensor)
unless type == {:u, 8} do
raise ArgumentError, "expected Nx.Tensor to have type {:u, 8}, got: #{inspect(type)}"
end
{height, width, channels} =
case Nx.shape(tensor) do
shape = {_height, _width, channels} when channels in 1..4 ->
shape
shape ->
raise ArgumentError,
"expected Nx.Tensor to have shape {height, width, channels}, got: #{inspect(shape)}"
end
data = Nx.to_binary(tensor)
content = <<height::32-big, width::32-big, channels::8, data::binary>>
new(content, :pixel)
end
end