View Source Picture Language
Install dependencies
Mix.install([
{:kino, "~> 0.3.0"},
{:vix, "~> 0.5"}
])
Defining helper function display
using kino so that we can show image inline
defmodule VixExt do
alias Vix.Vips.Image
alias Vix.Vips.Operation
@max_height 500
def show(%Image{} = image) do
height = Image.height(image)
# scale down if image height is larger than 500px
image =
if height > @max_height do
Operation.resize!(image, @max_height / height)
else
image
end
# write vips-image as png image to memory
{:ok, image_bin} = Image.write_to_buffer(image, ".png")
Kino.render(Kino.Image.new(image_bin, "image/png"))
:ok
end
end
Picture Language
Implementing picture language defined in Structural and Interpretation of Computer Programs section 2.2.4 in Elixir using vix
defmodule Pict do
alias Vix.Vips.Operation, as: Op
def beside(a, b) do
Op.resize!(Op.join!(a, b, :VIPS_DIRECTION_HORIZONTAL), 0.5, vscale: 1)
end
def below(a, b) do
Op.resize!(Op.join!(a, b, :VIPS_DIRECTION_VERTICAL), 1, vscale: 0.5)
end
def vert_flip(p) do
Op.flip!(p, :VIPS_DIRECTION_VERTICAL)
end
def horz_flip(p) do
Op.flip!(p, :VIPS_DIRECTION_HORIZONTAL)
end
end
Implementation of Fig. 2.9
defmodule PictUtils do
import Pict
def right_split(p, 0), do: p
def right_split(p, n) do
t = right_split(p, n - 1)
beside(p, below(t, t))
end
def up_split(p, 0), do: p
def up_split(p, n) do
t = up_split(p, n - 1)
below(beside(t, t), p)
end
def corner_split(p, 0), do: p
def corner_split(p, n) do
us = up_split(p, n - 1)
rs = right_split(p, n - 1)
beside(
below(beside(us, us), p),
below(corner_split(p, n - 1), below(rs, rs))
)
end
end
alias Vix.Vips.Image
import VixExt
{:ok, img} = Image.new_from_file("~/Downloads/kitty.png")
img = PictUtils.corner_split(img, 5)
right = Pict.below(img, Pict.vert_flip(img))
left = Pict.horz_flip(right)
img = Pict.beside(left, right)
show(img)