如何用matlab在Excel中畫畫 附源代碼

本文介紹如何用matlab控制Excel畫畫。
對於matlab和Excel你的認識不能僅僅停留在xlsread和xlswrite這兩個函數上,其實matlab對Excel的操作遠遠不止於此,詳情請見matlab和Excel的交互
所謂在Excel中畫畫,無非就是通過填充Excel單元格的背景色實現像素點的表達,都可以通過matlab中的Excel.Application實現。

try   % 打開Excel
    Excel=actxGetRunningServer('Excel.Application');
catch 
Excel=actxserver('Excel.application');
end

% 設置Excel可見

Excel.visible=1;

添加工作簿和工作表

Workbook=Excel.Workbooks.Add;
Sheet1=Workbook.Sheets.Item(1);

下面實現圖像的讀取,這裏用到了imread函數,可以讀取圖片的RGB值,用三維的數組存儲,數據格式爲uint8,但是Excel中是用24位的二進制表示顏色,前8位爲B,中間8位爲G,後8位爲R,所以需要先用double強制轉換數據類型。

A=imread('圖片路徑');
A=double(A);

然後就是分別得到R,G,B:

column=size(A,2);
row=size(A,1);
Red=A(:,:,1);
Green=A(:,:,2);
Blue=A(:,:,3);

爲了使得顏色設置更加方便,這裏我自己寫了一個RGB函數,用於將RGB轉換成Excel的格式:

function out=RGB(Red,Green,Blue)
if nargin~=3
    error('輸入參數錯誤,RGB輸入參數爲3個,分別爲RGB,0~255')
end
if length(Red)==length(Green)&length(Blue)==length(Green)
Red=Red;
Green=Green*2^8;
Blue=Blue*2^16;
out=Red+Green+Blue;
else
    error('輸入維度不匹配');
end
end

得到的輸出能夠直接給Excel使用。
修改Excel單元格的背景色可以使用以下代碼:

Sheet1.Range(範圍).Interior.Color = RGB;   
% 其中Sheet1爲工作表,Range內爲範圍 格式爲 'A1' 或‘A1:C3’

爲了能夠更方便得到範圍的正確格式,我也自己寫了一個格式轉換的函數,將座標值轉換成字母組合:

function Range=Cells(first,second)
% ======================================================================
% 輸入參數爲單個座標或者左上角以及右上角座標,返回結果可用於Excel的Range輸入
% Cells(first, second);
% first = n second = m; 或 first = [n1,m1],second = [n2 m2]
% ======================================================================
% 返回結果:
% Cells(1,2)---------------------------'A2'
% Cells([26*2 1],[26*27 1])------------ 'AZ1:ZZ1'
if nargin ==1
    if length(first)==2
        second=first(2);
        first=first(1);
    end
elseif nargin>2
    error('Cells輸入錯誤,輸入單元格座標或區域的對角座標');
end
if length(first)==length(second)&&length(first)==1
    if first<=0||second<=0
        error('座標不能小於1')
    end
    if first<=26
        charNum=1;
    elseif first<=26*26+26
        charNum=2;
    else
        error('圖片像素過大,請剪輯');
    end
    switch charNum
        case 1
            if mod(first,26)==0
                Column1='Z';
            else
                Column1=char('@'+mod(first,26));
            end
            Range=[Column1 num2str(second)];
            
        case 2
            first=first-26;
            if mod(first,26*26)==0
                Column1='Z';
            else
            Column1=char(floor(first/26)+'A');
            end
            if mod(first,26)==0
                Column2='Z';
                Column1=char(floor(first/26)+'@');
            else
                Column2=char('@'+mod(first,26));
            end
            Range=[Column1 Column2 num2str(second)];
    end
    
elseif length(first)==length(second)&&length(first)==2
    if first(1)<second(1)
        error('左上角座標在右下角座標前');
    end
    if sum(first>0)+sum(second>0)<4
        error('座標不能小於1')
    end
    if first(1)<=26
        charNum1=1;
    elseif first(1)<=26*26+26
        charNum1=2;
    else
        error('圖片像素過大,請剪輯');
    end
    switch charNum1
        case 1
            if mod(first(1),26)==0
                Column11='Z';
            else
                Column11=char('@'+mod(first(1),26));
            end
            Range1=[Column11 num2str(first(2))];
        case 2
            first(1)=first(1)-26;
            if mod(first(1),26*26)==0
                Column11='Z';
            else
            Column11=char(floor(first(1)/26)+'A');
            end
            if mod(first(1),26)==0
                Column12='Z';
                Column11=char(floor(first(1)/26)+'@');
            else
                Column12=char('A'+mod(first(1),26));
            end
            Range1=[Column11 Column12 num2str(first(2))];
    end
    if second(1)<=26
        charNum2=1;
    elseif second(1)<=26*26+26
        charNum2=2;
    else
        error('圖片像素過大,請剪輯');
    end
    switch charNum2
        case 1
            if mod(second(1),26)==0
                Column21='Z';
            else
                Column21=char('@'+mod(second(1),26));
            end
            Range2=[Column21 num2str(second(2))];
        case 2
            second(1)=second(1)-26;
            if mod(second(1),26*26)
                Column21='Z';
            else
            Column21=char(floor(second(1)/26)+'A');
            end
            if mod(second(1),26)==0
                Column22='Z';
                Column21=char(floor(second(1)/26)+'@');
            else
                Column22=char('A'+mod(second(1),26));
            end
            Range2=[Column21 Column22 num2str(second(2))];
    end
    Range=[Range1 ':' Range2];
else
    error('Cells輸入錯誤,輸入單元格座標或區域的對角座標');
end

最後通過一個二維的for循環即可實現自動填充,效果如下圖:
在這裏插入圖片描述
完整代碼如下:

try
    Excel=actxGetRunningServer('Excel.Application');
catch 
Excel=actxserver('Excel.application');
end
% 設置Excel可見
Excel.visible=1;
Workbook=Excel.Workbooks.Add;
Sheet1=Workbook.Sheets.Item(1);
A=imread('圖片路徑');
A=double(A);
column=size(A,2);
row=size(A,1);
Red=A(:,:,1);
Green=A(:,:,2);
Blue=A(:,:,3);
color=RGB(Red,Green,Blue);
tic
for a=1:size(color,2) % a爲列數
    for b=1:size(color,1) % b爲行數
Sheet1.Range(Cells(a,b)).Interior.Color =color(b,a);
    end
end
toc
Excel.Quit; % 關閉 Excel
Excel.delete; % 刪除對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章