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

Image hash

livebooks/vix/dhash.livemd

Image hash

Mix.install([
  {:image, "~> 0.38"},
  {:req, "~> 0.3"},
  {:kino, "~> 0.12"}
])

画像の読込

original_img =
  "https://www.elixirconf.eu/assets/images/drops.svg"
  |> Req.get!()
  |> Map.get(:body)
  |> Image.from_binary!()

類似画像生成

グレースケール

gray_img = Image.to_colorspace!(original_img, :bw)

リサイズ

resized_img = Image.resize!(original_img, 0.5)

回転

rotated_img = Image.rotate!(original_img, 45)

切り取り

cropped_img = Image.crop!(original_img, 0.07, 0.07, 0.9, 0.9)

文字追加

text_img = Image.Text.text!("Elixir", text_fill_color: :purple)

with_text_img = Image.compose!(original_img, text_img, x: 300, y: 100)

別画像

other_img =
  "https://hexdocs.pm/phoenix/assets/logo.png"
  |> Req.get!()
  |> Map.get(:body)
  |> Image.from_binary!()

画像の一覧表示

img_list =
  [
    original_img,
    gray_img,
    resized_img,
    rotated_img,
    cropped_img,
    with_text_img,
    other_img
  ]

Kino.Layout.grid(img_list, columns: 4)

ハッシュの計算

{:ok, original_dhash} = Image.dhash(original_img)
original_dhash_int = :binary.decode_unsigned(original_dhash, :big)
Integer.to_string(original_dhash_int, 16)
original_dhash_int
|> Integer.to_string(2)
|> String.pad_leading(64, "0")
other_img
|> Image.dhash()
|> elem(1)
|> :binary.decode_unsigned(:big)
|> Integer.to_string(2)
|> String.pad_leading(64, "0")

dHash 間のハミング距離

img_list
|> Enum.map(fn img ->
  hamming_distance =
    original_img
    |> Image.hamming_distance(img)
    |> elem(1)

  [hamming_distance, img]
  |> Kino.Layout.grid(columns: 1)
end)
|> Kino.Layout.grid(columns: 4)