画像をExcelにするMATLAB術

## 目次
[はじめに](#はじめに)
[画像を読み込む](#画像を読み込む)
[列番号をExcelに対応させる](#列番号をexcelに対応させる)
[背景色番号を抽出](#背景色番号を抽出)
[Cell型に変換](#cell型に変換)
[MATLABからExcelを操作しよう](#matlabからexcelを操作しよう)
[使用した関数](#使用した関数)
&emsp;[数字をExcelの列に対応する関数](#数字をexcelの列に対応する関数)
&emsp;[背景を塗りつぶす関数](#背景を塗りつぶす関数)
[結果](#結果)
[おわりに](#おわりに)
<a name="endToc"></a>
<a name="H_1074D69C"></a>
# はじめに

こんにちは、HerniaBabyです。


皆さんExcel大好きですよね？世間では[ネ申Excel](https://qiita.com/e99h2121/items/ef194c4fec579ec2c11c)といわれるものが世の中にはびこるくらい日本人はExcel大好きだと思っています。


もはやExcelは和の心、大和魂…。


そんなわけで今回は[画像を別の形式に変換するクソアプリ](https://qiita.com/de_teiu_tkg/items/f71e06e8cf7343453f2e)をMATLABでやっていきたいと思います。

<a name="H_B1BC89E7"></a>
# 画像を読み込む

まずは画像を読み込みましょう。


このときに方眼に色を書き込むんですが、画像がデカいとずっと計算が終わらないので[imresize](https://jp.mathworks.com/help/matlab/ref/imresize.html)で小さくしていきます。

```matlab
clc,close all,clear;
I = imread('chacha.jpeg');
I = imresize(I,[150 150]);
imshow(I)
```

![figure_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781521/1a3e1ce6-7637-90cb-42e7-1fd015963334.png)



画像は愛犬チャチャです。かわいいね( *´艸｀)

ここで画像の範囲を抜き出します。

```matlab
[row, col]  = size(I,1,2);
```
<a name="H_F62F11AF"></a>
# 列番号をExcelに対応させる

Excelは列がA...AA...AAAのような英語になっています。


列番号をこれに対応させる必要があります。


[MATLABで数字をExcelの列名に変換](https://qiita.com/hibs_MATLAB_Amb/items/edf096d73cdf671ddd8a)でMATLABアンバサダーの方が紹介してくれてますが、今回はMATLAB Answersのものを拾って使ってます。


[I need to convert a number into its column name equivalent](https://jp.mathworks.com/matlabcentral/answers/248797-i-need-to-convert-a-number-into-its-column-name-equivalent#answer_405713)

```matlab
col_e       = arrayfun(@int2xlcol, (1:col));
ImgString   = col_e + string((1:row)');
```

<a name="H_F5A7261A"></a>
# 背景色番号を抽出

RGB値を抜き出してExcelで使えるようにします。


最初は [Cody](https://jp.mathworks.com/matlabcentral/cody/groups/62/problems/1948) を参考にHex Stringに直してたんですが、結局[hex2dec](https://jp.mathworks.com/help/matlab/ref/hex2dec.html)に直してたのでそのままdouble型で出してます。


:::note warn


ExcelはBGRなので注意してください
[How to set excel cell color to red from Matlab?](https://jp.mathworks.com/matlabcentral/answers/3352-how-to-set-excel-cell-color-to-red-from-matlab#answer_240369)



:::

```matlab
I_d         = im2double(I);
[R,G,B]     = imsplit(I_d);
bgrColor    = (B.*256^2 + G.*256 + R).*255;
```
<a name="H_FE8A073B"></a>
# Cell型に変換

forループを使うとMATLABフリークスがマジギレするので[cellfun](https://jp.mathworks.com/help/matlab/ref/cellfun.html)を使います。


そのためcell配列に変換します。

```matlab
ImgCells        = cellstr(ImgString);
bgrColorCell    = num2cell(bgrColor);
```
<a name="H_431EFAA8"></a>
# MATLABからExcelを操作しよう

こいつのドキュメント本当に少なくて苦労しました。


**MathWorksさん！Excelは大和魂ぞ？！充実させてください(白目)**


今回は色んなところからかき集めたので説明していきます。


まずはパスを指定します。

```matlab
%Obtain the full path name of the file
filePath = fullfile(pwd, 'Book1.xlsx');
```

ExcelをActiveXで起動させます。

```matlab
%Open an ActiveX connection to Excel
h = actxserver('excel.application');
```

Excelファイルを開きます。

```matlab
%Open an excel file
wb = h.Workbooks.Open(filePath,0,false);
```

ここで各セルに背景色を書き込みます。

```matlab
cellfun(@(x,y) xlscolor(h, x, y), ImgCells, bgrColorCell)
```

行の高さと列の幅を正方形にします。


ハンドルプロパティどこあるのか苦労しました。


列幅はQiita([【MATLAB】Excel ファイルのセル幅自動調整](https://qiita.com/eigs/items/3a71c0da1744e48e9bca))にあったんですよね。高さが…。


ちなみに正方形の調整は以下を参考にしました。


[Excelの技：すべてのセルを正方形にして方眼紙のように！](https://xtech.nikkei.com/it/pc/article/knowhow/20090219/1012449/)

```matlab
range = ImgString(1,1)+":"+ImgString(end,end);
wbrange = wb.ActiveSheet.get('Range',range);
wbrange.EntireColumn.ColumnWidth = 1.88;
wbrange.EntireRow.RowHeight = 15;
```

最後に上書き保存してExcelを閉じます。

```matlab
% save the file with the given file name, close Excel
wb.Save;
wb.Close;
h.Quit;
h.delete;
disp('完了')
```

```TextOutput
完了
```
<a name="H_8CDBDA6A"></a>
# 使用した関数
<a name="H_112A99A5"></a>
## 数字をExcelの列に対応する関数
```matlab
function str = int2xlcol(num)    
    raw = 'A':'Z';
    str = raw(1+rem(num-1,26));
    tmp = fix((num-1)/26);
    while any(tmp)
        str = [raw(1+rem(tmp-1,26)),str]; %#ok<AGROW>
        tmp = fix((tmp-1)/26);
    end
    str = string(str);
end
```
<a name="H_ED1FD466"></a>
## 背景を塗りつぶす関数
```matlab
function xlscolor(h, range, Color)
    ran = h.Activesheet.get('Range',range);
    ran.interior.Color = Color;
end
```
<a name="H_72B2E919"></a>
# 結果

けっこうよくないですか？！

![image_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781521/500377bf-6b40-34a5-1353-a97efc7f5e0d.png)


アップするとこんな感じです↓

![image_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781521/77aa82f5-5616-b4b0-ff24-49b0612bed68.png)



てことで完成です。

<a name="H_73BA0EEC"></a>
# おわりに

今回は業務に関連するものではなく気ままに作りました。


応用すると昔流行った[ExcelでBadApple](https://youtube.com/shorts/-2mYZpqF2VE?si=xWCxYa60Mb8l-x7S)なんかも出来そうですね。


cellfun使ったんですがやり方が悪いのか計算が遅いんですよね。


誰か行列を指定して一気に背景色反映させる方法知りません？


知ってたら教えてください。

**2023.12.07追記**
MATLAB Answersでも聞いてみましたが、値(Value)のみが一括で変更できるみたいです。
[MATLABからEx​celの背景色を一括​で変えたい](https://jp.mathworks.com/matlabcentral/answers/2057469-matlab-excel?s_tid=prof_contriblnk)

**2023.12.11追記**
目次でアルファベット入れる場合はリンクのものを小文字にする必要があるんですね。
[目次にアルファベットを打っても効果なしですか？](https://qiita.com/alce/questions/602f43e0bea37c0acdde#2-Markdown%E6%96%B9%E5%BC%8F)

**2023.12.11追記**
[GitHub](https://github.com/HerniaBaby/Image2Excel.git)にも掲載しました。
何気に初めてやりました。