スプレッドシートを画像ビューアとして使う方法

この記事はISer Advent Calendar 2022の3日目として書かれました。

adventar.org

書くことが何も思いつかなかったので、おそらく世界のだれも必要としていない記事を書きます。

皆さんはエクセルアートって知っていますか?私もよく知らないのですが、以前ネット上で見かけて感銘を受けました。 press.share-wis.com

これと同じ感じで、マクロとかを使えばエクセルを画像ファイルビューアとして使うことができそうじゃないですか。できると思うんです。というわけでやってみました。私はエクセルのマクロとかよくわからないので、馴染みのあるGoogle SpreadsheetとGoogle Apps Script (GAS)を使ってみました。これ便利ですよ。

とりあえず適当な画像を用意します。ここでは私のTwitterのアイコン画*1を使っていこうと思います。

ファイル名は400x400となっていたのに実サイズは232x232でした。解せぬ

まずは以下のPythonスクリプトを実行します。Apps Script使うと言っていたのにいきなりPythonかよ?!という感じですが、Apps Scriptにはいい感じの画像処理ライブラリがなさそうだったので。

import numpy as np
from PIL import Image

WIDTH = 232
HEIGHT = 232

img = Image.open('sample.jpg')
arr = np.array(img)

np.savetxt('red.csv', arr[:,:,0], fmt='%d', delimiter=',')
np.savetxt('green.csv', arr[:,:,1], fmt='%d', delimiter=',')
np.savetxt('blue.csv', arr[:,:,2], fmt='%d', delimiter=',')

するとred.csv, green.csv, blue.csvという3つのファイルが作成されます。

次にChromeを開いてGoogleスプレッドシートを新規作成します。

先ほど生成した3つのCSVファイルを「ファイル > インポート」からシートとしてインポートして、

拡張機能 > Apps Script」から以下のコードを追加します。

function createCanvas(sheet, width, height) {
  const cols = sheet.getMaxColumns();
  if (cols < width) sheet.insertColumns(1, width - cols);
  const rows = sheet.getMaxRows();
  if (rows < height) sheet.insertRows(1, height - rows);

  sheet.setColumnWidths(1, width, 2);
  sheet.setRowHeights(1, height, 2);
}

function render() {
  const width = 232;
  const height = 232;
  const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = spreadSheet.getSheetByName('main');
  createCanvas(sheet, width, height);

  const red = spreadSheet
    .getSheetByName('red')
    .getRange(1, 1, height, width)
    .getValues();
  const green = spreadSheet
    .getSheetByName('green')
    .getRange(1, 1, height, width)
    .getValues();
  const blue = spreadSheet
    .getSheetByName('blue')
    .getRange(1, 1, height, width)
    .getValues();

  for (let i = 0; i < width; i++) {
    for (let j = 0; j < height; j++) {
      const cell = sheet.getRange(i+1, j+1);
      cell.setBackgroundRGB(red[i][j], green[i][j], blue[i][j]);
    }
  }
}

render関数を実行してしばらく待つと、

無事に画像が表示されました。なぜか少し横長ですが気にしないことにします。

カラーの反転も簡単にできます。すごいね!

なお、スプレッドシートを画像ビューアとして使うことはおすすめしません。200ピクセル四方程度の画像1つ表示するのに数分とかかかるし、バカみたいにメモリ食います。

一人黙々とメモリを食べ続けるChrome

ちゃんと専用のソフトを使いましょう。

結論

Google Apps Scriptは便利で楽しいのでみんなで使いましょう。

*1:お前のTwitterのアイコン画像何?と思っている人いると思うのですが、これはキテレツ大百科という90年代くらいに放送されていたアニメのキャラクターです。小さい頃再放送でよく見ていました。画像は拾い画です。コラっぽいですがコラではないです。特に意味はありません。