GrapeCity.devlog

グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉の最新情報をお届けします。製品のTIPSや発売情報、イベントのお知らせなどをいち早く発信中です。

Excelのセルに色を塗って画像を描く

Excelの目的外利用

Excelは幅広い用途で使え、応用力が半端ない素晴らしいアプリケーションです。
そのため、すぐに主目的の用途以外で利用することを考えてしまいます。

Excelを文書作成に使ったり、いわゆるExcel方眼紙はビジネスでも利用できるので、賛否両論があります。
また、絵をかいてみた、ゲームを作ってみた、などのツワモノは世界中にたくさんいます。その多くは日本にいるともいわれていますが…

さて、この記事のもそのような目的外利用がテーマです。
ドキュメントAPIライブラリの「DioDocs(ディオドック)」シリーズで、Excelファイルを生成できますので、セルを1つの要素として利用した画像、いわゆるドット絵を描いてみたいと思います。


ドット絵と言えば…

1983年に登場し多くの家庭に普及した任天堂のファミリーコンピュータ(通称:ファミコン)は、当時のコンピュータ技術の限界もあり、ゲームに登場するキャラクターは粗い画像で表現されていました。
低い解像度で表現するため、ひとつの色を1ドットで表示しその組み合わせで小さなキャラクターを作成しています。
そのような"雑"な制限がありながらも、世界的な大人気キャラクターになったのが「マリオ」です。

今回は、人気ゲーム「スーパーマリオブラザース」"1-1"面のスタート時の姿をドット絵で表現してみます。
上記「マリオって?」サイトのアイコンにも設定してあるおなじみの画像です。

ドット絵の構成

まず下準備です。
マリオのドット絵は16×16のマス目に分解して考えます。
その256個に分割したマス目を、Excelで16行×16行=256個のセルとして表現することにします。

また、マリオのドット絵は3色で構成されているようです。3色に背景色を含めた合計4色を256個のセルに割り当てれば画像として見えるはずです。
各セルの背景色を以下4色のいずれかに塗ることで表現します。色には、0から3までの番号を割り当てておきます。

番号
0 背景色
1 色1
2 色2
3 色3

次に各セルにどの色を塗るかの指定です。
これは二次元配列を利用して構成します。
左から順番に、背景色、色1、色2、色3と並べる指定です。2行目も同様です。

{0,1,2,3},
{1,0,3,0}

この配列の値に基づいて、表番号の色を指定すると以下のように2段の色の並びができあがります。


配列を作ってその通りに指定した色を並べれば、さまざまなドット絵になります。

この色情報をセルのひとつひとつに手入力していくことで作ることができます。しかしそれでは、手間がかかりますし応用がききません。
そこでExcelのマクロで実行するのが現実的ですが、今回はC#で.NET Coreコンソールアプリを作成します。
DioDocs for Excelを利用して、ドット絵を描いたExcelファイルを生成するアプリです。

コンソールアプリの作成

.NET Coreのコンソールアプリを作るための事前準備は、DioDocsの製品ドキュメントやブログ記事に記載があるのでここでは省略します。詳しくはこちらを参照してください。

なお、コマンド部分だけを切り出すと以下です。

mkdir DioDocs
cd DioDocs
dotnet new console 
dotnet add package GrapeCity.DioDocs.Excel.ja 
code . 

手順どおりに作成するとNuGet.orgから取得したDioDocs for Excelのパッケージが組み込み済みのプロジェクトが使えるようになります。

画像情報の作成

アプリ作成の準備はできたものとして、C#のコードを記述します。
まずは、利用する色の指定です。前述の4色の情報を格納するListクラスを作成します。

List<string> color = new List<string>();
// 使用する4色を設定
color.Add("#FFFFFF");
color.Add("#FF3300");
color.Add("#FF9933");
color.Add("#996600");

次は画像情報です。Objectクラスの二次元配列を作成します。
1行に16個の値(指定する色の番号)を設定した配列を、16行分作ることで16×16画像の設計図が完成します。
画面から離れて目を細めると、ぼんやりとシルエットが浮かび上がります。

object[,] charData = new object[,]
{
    {0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
    {0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0},
    {0,0,0,0,3,3,3,2,2,3,2,0,0,0,0,0},
    {0,0,0,3,2,3,2,2,2,3,2,2,2,0,0,0},
    {0,0,0,3,2,3,3,2,2,2,3,2,2,2,0,0},
    {0,0,0,3,3,2,2,2,2,3,3,3,3,0,0,0},
    {0,0,0,0,0,2,2,2,2,2,2,2,0,0,0,0},
    {0,0,0,0,3,3,1,3,3,3,0,0,0,0,0,0},
    {0,0,0,3,3,3,1,3,3,1,3,3,3,0,0,0},
    {0,0,3,3,3,3,1,1,1,1,3,3,3,3,0,0},
    {0,0,2,2,3,1,2,1,1,2,1,3,2,2,0,0},
    {0,0,2,2,2,1,1,1,1,1,1,2,2,2,0,0},
    {0,0,2,2,1,1,1,1,1,1,1,1,2,2,0,0},
    {0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0},
    {0,0,0,3,3,3,0,0,0,0,3,3,3,0,0,0},
    {0,0,3,3,3,3,0,0,0,0,3,3,3,3,0,0},
};

Excelシートの作成

次はExcelワークブック、シートの操作です。
今回は1つのワークブックを作成して2つのシートを作ります。
1枚目のシートに、前述の配列を16進数のRGB情報に置き換えた文字列を設定し、2枚目のシートにその色情報でセルの背景色を塗りつぶした状態に設定、つまりドット絵を描きます。

// ワークブック作成
Workbook workbook = new Workbook(); 
// 1枚目のシートをワークシートオブジェクトに取得
IWorksheet worksheet = workbook.ActiveSheet; 
//2枚目のシートを追加
IWorksheet worksheetimg = workbook.Worksheets.Add(); 

ワークシートの操作方法は、DioDocs for Excelのデモ*1で紹介しています。

画像を表示する2枚目ワークシート用に以下の設定を追加します。 画像として見やすくするために、グリッド線を非表示にして画像を行、列ヘッダーから離して表示するように位置を指定します。

//グリッド線は表示しない
worksheetimg.SheetView.DisplayGridlines = false; 
// シート内の表示位置を指定
int startX = 0, startY = 0;
int offsetX = 5, offsetY = 10;

セルの塗りつぶし

画像の色情報を指定した二次元配列から色番号を取得して、それを基に色情報に置き換えます。
色情報は1枚目のシートに保存しておきます。

// 二次元配列から指定場所に設定する色番号を取得
var htmlcolor = color[int.Parse(charData[y,x].ToString())]; 
// 1枚目のシートに色情報を設定
worksheet.Range[y,x].Value = htmlcolor;

セルを塗りつぶすためには、セル範囲を取得してそのInterior.Colorプロパティに色を指定します。
以下のコードでは、作成する画像のオフセット位置を指定し、そのセルを前のコードで指定した色で塗りつぶす処理を実行しています。
セル範囲の操作はDioDocs for Excelのデモ*2で紹介しています。

// 2枚目のシートから色を塗りつぶす対象のセルを取得
var range = worksheetimg.Range[y + offsetY, x + offsetX];
// 16進数の色情報からColorクラスを取得し、 セルの内部色を塗りつぶす設定
range.Interior.Color = ColorTranslator.FromHtml(htmlcolor);

セルを塗りつぶす方法は、DioDocs for Excelの*3デモで紹介しています。

ここでは、16進数の色情報からColorに変換するためにColorTranslatorクラスのFromHtmlメソッドを利用しています。
このクラスを利用するためには、プロジェクトにSystem.Drawing.Commonパッケージの追加が必要です。 これは.NET Coreで利用できるパッケージなので、Nuget.orgから取得することができます。

ターミナルで.NET Core CLIを起動し、以下のコマンドで取得可能です。

dotnet add package System.Drawing.Common

Nuget.orgからダウンロードし、自動的にプロジェクトに組み込まれます。

この処理を二次元配列の要素数分繰り返し実行すれば、16×16=256個のセルが指定色で塗りつぶされ、画像が描かれます。 最後に作成したワークブックをExcelファイルに保存するSaveメソッドを実行すればできあがりです。

workbook.Save("DrawChar.xlsx");

dotnet runコマンドで実行すると、同じフォルダにDrawChar.xlsxが完成するのでExcelで確認できます。
1枚目のシートは色情報で、画像を描いた2枚目のシートがその下です。

シート1
シート2

セルを方眼紙のように調整する

ひとつ処理が抜けていました。
Excel方眼紙を作るための準備でおなじみ、セルを正方形にする処理です。
指定したセル範囲について、行の高さ:RowHeightInPixelと、列の幅:ColumnWidthInPixelを、ピクセル単位で指定します。

range.RowHeightInPixel = range.ColumnWidthInPixel =15;

セルの高さの設定方法は、DioDocs for Excelのデモ*4で紹介しています。

この処理を含めた最終的な実行結果については、「マリオの画像そのもの」になるのでここではスクリーンショットは割愛します。
最初に定義した色と、画像情報の配列情報で、以下のコードで実行するとExcelファイルが作成できます。
また、Nuget.orgから取得したDioDocsのパッケージは、無料で利用できますのでお試しください。

using System;
using System.Collections.Generic;
using System.Drawing;
using GrapeCity.Documents.Excel;

namespace DrawChar
{
    class Program
    {
        static void Main(string[] args)
        {
            // 画像の色情報配列
            object[,] charData = new object[,]
            {
                {0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
                // 省略 
                {0,0,3,3,3,3,0,0,0,0,3,3,3,3,0,0},
            };
            // 使用する色
            List<string> color = new List<string>();
            color.Add("#F0F0F0");
            color.Add("#FF3300");
            color.Add("#FF9933");
            color.Add("#996600");

            // ワークブック作成
            Workbook workbook = new Workbook(); 
            // 1枚目のシートをワークシートオブジェクトに取得
            IWorksheet worksheet = workbook.ActiveSheet; 
            //2枚目のシートを追加
            IWorksheet worksheetimg = workbook.Worksheets.Add(); 

            //グリッド線は表示しない
            worksheetimg.SheetView.DisplayGridlines = false; 
            // シート内の表示位置を指定
            int startX = 0, startY = 0;
            int offsetX = 5, offsetY = 10;

            // 配列のループ処理
            for (int y = startY; y < charData.GetLength(1); y++)
            {
                for (int x = startX; x < charData.GetLength(0); x++)
                {
                    // 二次元配列から指定場所に設定する色番号を取得
                    var htmlcolor = color[int.Parse(charData[y,x].ToString())]; 
                    // 1枚目のシートに色情報を設定
                    worksheet.Range[y,x].Value = htmlcolor;

                    // 2枚目のシートから色を塗りつぶす対象のセルを取得
                    var range = worksheetimg.Range[y + offsetY, x + offsetX];
                    // 16進数の色情報からColorクラスを取得し、 セルの内部色を塗りつぶす設定
                    range.Interior.Color = ColorTranslator.FromHtml(htmlcolor);
                    // 対象セルの高さと幅を合わせて正方形に設定
                    range.RowHeightInPixel = range.ColumnWidthInPixel =15;
                }
            }
            // Excelファイルを保存
            workbook.Save("DrawChar.xlsx");
        }
    }
}

DioDocs for Excelの機能

このアプリを作成する際に利用したDioDocs for Excelの各機能は、以下の各デモアプリケーションで体験できます。