はじめに
R言語で画像処理を行うmagick
パッケージを確認します。
この記事では、image_scale()
により画像を変形します。
【この記事の内容】
magick::image_scale関数
magick
パッケージの画像サイズを整形する関数image_scale()
を確認します。より細かく設定したい場合はimage_resize()
の方がいいようですが(?)扱いません。
利用するパッケージを読み込みます。
# 利用パッケージ library(magick) library(tidyverse)
この記事では、基本的にパッケージ名::関数名()
の記法を使うので、パッケージを読み込む必要はありません。ただし、作図コードがごちゃごちゃしないようにパッケージ名を省略しているため、ggplot2
は読み込む必要があります。
また、ネイティブパイプ演算子|>
を使っています。magrittr
パッケージのパイプ演算子%>%
に置き換えても処理できますが、その場合はmagrittr
も読み込む必要があります。
画像の作成
まずは、例として利用するための画像ファイルを作成します。のヒートマップを例とします。
x軸とy軸の値を指定して、z軸の値を計算します。
# x軸とy軸の値を作成 x_vals <- seq(from = 1, to = 4, by = 1) y_vals <- seq(from = 1, to = 3, by = 1) # 作図用のデータフレームを作成 df <- tidyr::expand_grid(x = x_vals, y = y_vals) |> # 格子点を作成 dplyr::mutate(z = x + y) df
## # A tibble: 12 × 3 ## x y z ## <dbl> <dbl> <dbl> ## 1 1 1 2 ## 2 1 2 3 ## 3 1 3 4 ## 4 2 1 3 ## 5 2 2 4 ## 6 2 3 5 ## 7 3 1 4 ## 8 3 2 5 ## 9 3 3 6 ## 10 4 1 5 ## 11 4 2 6 ## 12 4 3 7
x軸の値をx_vals
、y軸の値をy_vals
を作成して、x_vals, y_vals
の格子状の点(全ての組み合わせ)をexpand_grid()
で作成しx軸とy軸の値を足します。
ヒートマップを作成します。
# ヒートマップを作成 g <- ggplot(data = df, mapping = aes(x = x, y = y, fill = z)) + geom_tile(show.legend = FALSE) + # ヒートマップ geom_text(mapping = aes(label = paste0("(", x, ", ", y, ")")), color = "white", size = 10) + # 座標ラベル scale_x_continuous(breaks = x_vals) + scale_y_continuous(breaks = y_vals) + scale_fill_gradient(low ="gold", high = "red") + # グラデーション coord_equal(clip = "off", expand = FALSE) + # アスペクト比 labs(title = "Heatmap", subtitle = "(x, y)") g
geom_tile()
でヒートマップを描画します。格子点を渡す必要があります。
(資料作成時の仕様がよく分からず、この図と書き出し・読み込み後の図の体裁が変わってますが気にしないでください…)
作成したグラフを画像ファイルとして書き出します。
# 画像を書き出し ggplot2::ggsave( filename = "heatmap.png", plot = g, width = max(x_vals)*200, height = max(y_vals)*200, units = "px", dpi = 100 )
ggsave()
でpngファイルとして保存します。
画像サイズの変換
では、image_scale()
を利用して画像サイズを変形する際の仕様(指定方法)を確認していきます。
画像ファイルを読み込みます。
# 画像を読み込み pic_data <- magick::image_read(path = "heatmap.png") pic_data
image_read()
にファイルパスを指定して、画像ファイルを読み込みます。
画像情報を確認します。
# 画像情報を取得 pic_info <- magick::image_info(image = pic_data) pic_info
## # A tibble: 1 × 7 ## format width height colorspace matte filesize density ## <chr> <int> <int> <chr> <lgl> <int> <chr> ## 1 PNG 800 600 sRGB FALSE 26977 39x39
image_info()
で画像サイズなどを確認できます。
横サイズ(横方向のピクセル数)が800
、縦サイズ(縦方向のピクセル数)が600
なのが分かります。
image_scale()
のgeometry
引数に変形後のサイズを指定します。
横サイズを指定する場合は、文字列でサイズを指定します。
# 横サイズを指定してリサイズ:アスペクト比固定 pic_scaled_w <- magick::image_scale(image = pic_data, geometry = "700") pic_scaled_w |> magick::image_info() pic_scaled_w
## # A tibble: 1 × 7 ## format width height colorspace matte filesize density ## <chr> <int> <int> <chr> <lgl> <int> <chr> ## 1 PNG 700 525 sRGB FALSE 0 39x39
縦横比が保たれるように縦サイズが決まります。
縦サイズを指定する場合は、x
の後にサイズを指定します。
# 縦サイズを指定してリサイズ:アスペクト比固定 pic_scaled_h <- magick::image_scale(image = pic_data, geometry = "x700") pic_scaled_h |> magick::image_info() pic_scaled_h
## # A tibble: 1 × 7 ## format width height colorspace matte filesize density ## <chr> <int> <int> <chr> <lgl> <int> <chr> ## 1 PNG 933 700 sRGB FALSE 0 39x39
縦横比が保たれるように横サイズが決まります。
x
の前に横サイズの上限、後ろに縦サイズの上限を指定すると、それぞれの値を超えない範囲で縦横比を保って変形します。
# 縦横サイズを指定してリサイズ:アスペクト比固定 pic_scaled_wh <- magick::image_scale(image = pic_data, geometry = "750x750") pic_scaled_wh |> magick::image_info() pic_scaled_wh
## # A tibble: 1 × 7 ## format width height colorspace matte filesize density ## <chr> <int> <int> <chr> <lgl> <int> <chr> ## 1 PNG 750 563 sRGB FALSE 0 39x39
横サイズと縦サイズがそれぞれ750
を超えていないのが分かります。
縦横比を保たずに値を指定する場合は、文字列の最後に!
を付けます。
# 横サイズを指定してリサイズ:アスペクト比変更 pic_scaled_wh <- magick::image_scale(image = pic_data, geometry = "750x750!") pic_scaled_wh |> magick::image_info() pic_scaled_wh
## # A tibble: 1 × 7 ## format width height colorspace matte filesize density ## <chr> <int> <int> <chr> <lgl> <int> <chr> ## 1 PNG 750 750 sRGB FALSE 0 39x39
横サイズと縦サイズがそれぞれ750
になっているのが分かります。
さらに、横x縦+x+y
と指定する方法もあるのですが、よく分からなかったので飛ばします。
この記事では、magick
パッケージのimage_scale()
を解説しました。次の記事では、magick
パッケージを使ってアニメーションを作成します。
参考
おわりに
記事上だと最後以外は変形されているのか分かりませんね、、、手元の資料では分かったんです。一応アスペクト比が変わっていないだろうことと、画像情報を見るとサイズが変わっていることが分かりますし、この記事はおまけのおまけのようなものなので、これでよしとします。
【次の内容】