Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Draw

livebooks/vix/draw.livemd

Draw

Mix.install([
  {:image, "~> 0.54"},
  {:req, "~> 0.5"},
  {:kino, "~> 0.14"}
])

画像の生成

Image.new!(100, 200)
|> Image.Kino.show()
Image.new!(200, 200, color: "#FF0000")
|> Image.Kino.show()
Image.new!(200, 200, color: [0, 255, 0])
|> Image.Kino.show()
Image.new!(200, 200, color: :blue)
|> Image.Kino.show()
Image.Color.color_map()
img = Image.new!(100, 100)

Image.Kino.show(img)

図形描画

img
|> Image.Draw.point!(80, 30, color: :white)
|> Image.resize!(5)
|> Image.Kino.show(max_height: 500)

直線

img
|> Image.Draw.line!(10, 20, 30, 40, color: :white)
|> Image.resize!(5)
|> Image.Kino.show(max_height: 500)

四角形

{left, top, width, height} = {10, 20, 30, 40}
img
|> Image.Draw.rect!(left, top, width, height, color: :blue)
|> Image.Kino.show()
img
|> Image.Draw.rect!(left, top, width, height, color: :green, fill: false)
|> Image.Kino.show()

塗りつぶし

color = "#FF0000"

img
|> Image.Draw.rect!(left, top, width, height, color: color, fill: false)
|> Image.Draw.flood(left + 10, top + 10, color: color)
|> elem(1)
|> elem(0)
|> Image.Kino.show()
img
|> Image.Draw.rect!(left, top, width, height, color: color, fill: false)
|> Image.Draw.flood(left + 10, top + 10, color: color)
thickness = 8

img
# 外側の枠
|> Image.Draw.rect!(left, top, width, height, color: color, fill: false)
# 内側の枠
|> Image.Draw.rect!(
  left + thickness,
  top + thickness,
  width - thickness * 2,
  height - thickness * 2,
  color: color,
  fill: false
)
# 塗りつぶし
|> Image.Draw.flood(left + 1, top + 1, color: color)
|> elem(1)
|> elem(0)
|> Image.Kino.show()

{center_x, center_y, radius} = {30, 40, 20}
img
|> Image.Draw.circle!(center_x, center_y, radius, color: :blue)
|> Image.Kino.show()
img
|> Image.Draw.circle!(center_x, center_y, radius, color: :green, fill: false)
|> Image.Kino.show()
thickness = 4
color = :red

img
|> Image.Draw.circle!(center_x, center_y, radius, color: color, fill: false)
|> Image.Draw.circle!(
  center_x,
  center_y,
  radius - thickness,
  color: color,
  fill: false
)
|> Image.Draw.flood(center_x - radius + 1, center_y, color: color)
|> elem(1)
|> elem(0)
|> Image.Kino.show()

多角形

Image.Shape.polygon!(
  [
    [100, 20],
    [20, 180],
    [180, 180]
  ],
  width: 200,
  height: 100,
  opacity: 1.0,
  fill_color: :red,
  stroke_color: :blue,
  stroke_width: 8
)
|> Image.Kino.show()
Image.Shape.polygon!(
  5,
  fill_color: :green,
  opacity: 0.5,
  radius: 100,
  rotation: 90
)
|> Image.Kino.show()
star_img = Image.Shape.star!(5, width: 100, opacity: 1.0, fill_color: :yellow)

Image.Kino.show(star_img)
Image.Shape.star!(10, inner_radius: 20, outer_radius: 180, opacity: 1.0, fill_color: :yellow)
|> Image.Kino.show()

文字描画

Image.Text.text!("Hello, Livebook!", background_fill_color: :black)
|> Image.Kino.show()
text_image =
  Image.Text.text!(
    "Hello, Livebook!",
    font_weight: 600,
    text_fill_color: :yellow,
    background_fill_color: :green,
    background_fill_opacity: 1.0,
    background_stroke_color: :blue,
    background_stroke_width: 4,
    background_stroke_opacity: 1.0,
    padding: 8,
    font_size: 54
  )

Image.Kino.show(text_image)

画像との合成

ryo_img =
  "https://www.elixirconf.eu/assets/images/ryo-wakabayashi.jpg"
  |> Req.get!()
  |> Map.get(:body)
  |> Image.from_binary!()

Image.Kino.show(ryo_img, max_height: 400)
ryo_img
|> Image.compose!(star_img, x: 30, y: 100)
|> Image.Draw.image(text_image, 10, 10)
|> elem(1)
|> Image.Kino.show(max_height: 400)
star_img =
  Image.Shape.star!(10,
    inner_radius: 20,
    outer_radius: 180,
    width: 100,
    opacity: 1.0,
    fill_color: :yellow
  )

rect_img =
  Image.Shape.polygon!(4,
    width: 180,
    height: 200,
    opacity: 1.0,
    stroke_color: :red,
    stroke_width: 32,
    rotation: 45
  )

text_image = Image.Text.text!("Hello, Livebook!", text_fill_color: :blue, font_size: 54)

ryo_img
|> Image.compose!(star_img, x: 30, y: 100)
|> Image.compose!(rect_img, x: 190, y: 200)
|> Image.compose!(text_image, x: 10, y: 10)
|> Image.Kino.show(max_height: 400)