Introduction View Source
Install dependencies
Mix.install([
{:kino, "~> 0.3.0"},
{:vix, "~> 0.5"}
])
# print vips version
IO.puts("Version: " <> Vix.Vips.version())
Vips Image IO
All image IO operations such as reading and writing files are available in Vix.Vips.Image
module. Image module also contains functions get image attributes. Most Vips operations takes %Vix.Vips.Image{}
instance
alias Vix.Vips.Image
Reading image from a file. Note that image is not actually loaded to the memory at this point. img is %Image{}
struct.
{:ok, %Image{} = img} = Image.new_from_file("~/Downloads/kitty.png")
Writing Image
to a file. Image type selected based on the image path extension. See documentation for more options
:ok = Image.write_to_file(img, "kitty.jpg[Q=90]")
# let's print image dimensions
IO.puts("Width: #{Image.width(img)}")
IO.puts("Height: #{Image.height(img)}")
Kino supports showing image inline. We can use this to display image in the livebook. This opens gate for exploratory image processing
defmodule VixExt do
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
import VixExt
# Lets see show in action
show(img)
Vips Operations
All image processing operations are available in Vix.Vips.Operation
alias Vix.Vips.Operation
Crop
Getting a rectangular region from the image
{:ok, extract_img} = Operation.extract_area(img, 100, 50, 200, 200)
show(extract_img)
Thumbnail.
This function accepts many optional parameters, see vips thumbnail doc for more details.
Also see Operation.thumbnail/3
which accepts image path
{:ok, thumb} = Operation.thumbnail_image(img, 100)
show(thumb)
Resize
Resize image to 400x600. resize
function accepts scaling factor.
Skip vscale
if you want to preserve aspect ratio
hscale = 400 / Image.width(img)
vscale = 600 / Image.height(img)
{:ok, resized_img} = Operation.resize(img, hscale, vscale: vscale)
show(resized_img)
Flip
direction =
case IO.gets("Direction: ") do
"horizontal\n" -> :VIPS_DIRECTION_HORIZONTAL
"vertical\n" -> :VIPS_DIRECTION_VERTICAL
end
{:ok, flipped_img} = Operation.flip(img, direction)
show(flipped_img)
Text
Text operation takes multiple optional parameters. See libvips doc for more details
str = String.trim(IO.gets("Text: "))
{:ok, {text, _}} = Operation.text(str, dpi: 300, rgba: true)
# add text to an image
{:ok, inserted_text_img} = Operation.composite2(img, text, :VIPS_BLEND_MODE_OVER, x: 50, y: 20)
show(inserted_text_img)
Few more operations
# Gaussian blur
{:ok, blurred_img} = Operation.gaussblur(img, 5)
show(blurred_img)
# convert image to a grayscale image
{:ok, bw_img} = Operation.colourspace(img, :VIPS_INTERPRETATION_B_W)
show(bw_img)
# adding gray border
{:ok, extended_img} =
Operation.embed(img, 10, 10, Image.width(img) + 20, Image.height(img) + 20,
extend: :VIPS_EXTEND_BACKGROUND,
background: [128]
)
show(extended_img)
# rotate image 90 degree clockwise
{:ok, rotated_img} = Operation.rot(img, :VIPS_ANGLE_D90)
show(rotated_img)
# join two images horizontally
{:ok, main_img} = Image.new_from_file("~/Downloads/kitten.svg")
{:ok, joined_img} = Operation.join(img, main_img, :VIPS_DIRECTION_HORIZONTAL, expand: true)
show(joined_img)