在MATLAB中向Excel单元格插入图片

4
我正在跟随这篇文章,我需要做类似的事情,只是我想把一个图像(m x n x 3矩阵)放入Excel中的单元格中。
因为我的图像im是一个矩阵而不是句柄,所以这行代码不起作用:
print(im, '-dbitmap');

我需要为这张图片创建一个句柄吗?是否有其他更好的方法?

最终,我希望更改单元格的大小以适应图片(而不更改图片的大小)。


你想将一个矩阵作为图像插入到Excel文档中吗?为什么不插入原始数据呢? - Wolfie
一张图片就是一个矩阵。而这张图片是我在Matlab中进行操作后的输出结果。 - havakok
2个回答

5

print语句将图形窗口的内容打印到文件中,因此您需要先绘制图像:

image(im);                        % Plot image
set(gca, 'Visible', 'off', ...    % Turn off axes visibility
         'Position', [0 0 1 1]);  %   and make axes fill figure window
hFigure = gcf;                    % Get handle to figure
pos = get(hFigure, 'Position');   % Get current figure position
set(hFigure, 'Position', [pos(1:2) size(im, 2) size(im, 1)]);  % Set position so image
                                                               %   is scaled properly

然后,您可以创建一个COM服务器,并将图形打印到Excel文件中,如下所示:
excel = actxserver('Excel.Application');  % Create server object
excelWorkbook = excel.Workbooks.Add(1);   % Add a workbook
excelSheet = excel.ActiveSheet;           % Get the active sheet

dpi = get(groot, 'ScreenPixelsPerInch');  % Get screen dpi
print(hFigure, sprintf('-r%d', dpi), ...  % Print the figure at the screen resolution
      '-clipboard', '-dbitmap');          %   to the clipboard as a bitmap
excelSheet.Range('B2').PasteSpecial();    % Paste from clipboard (top left corner
                                          %   of image will be in the cell 'B2')

excelSheet.Range('B2').RowHeight = ...    % Set cell height to image height
  excelSheet.Shapes.Item(1).Height;
widthScale = excelSheet.Range('B2').ColumnWidth./...  % Column width (in characters)
             excelSheet.Range('B2').Width;            % Column width (in points)
excelSheet.Range('B2').ColumnWidth = ...  % Set cell width to scaled image width
  excelSheet.Shapes.Item(1).Width.*widthScale;

excelWorkbook.SaveAs('figtest.xlsx');  % Save workbook to a file
excelWorkbook.Close();                 % Close workbook
excel.Quit();                          % Quit server
excel.delete();                        % Delete server object

上述尝试缩放单元格以适应整个图像。这适用于行高,但由于某种原因列宽度不正确。由于列宽度是根据字符定义的,而图像宽度是根据点/英寸定义的,因此确定合适的缩放比例似乎非常困难。我不确定是否有好的解决方法。
例如,这是示例MATLAB图像'peppers.png'的结果。

enter image description here


这只是将图像浮动在Excel中,而不是将图像适合单元格。有没有办法将其适合单元格? - havakok
@havakok:不确定。到目前为止,我尝试了一些无效的方法。需要再仔细研究一下。 - gnovice
@havakok:我更新了答案,展示了如何将图像高度缩放到单元格高度以适应单元格中的图像。这是你想要的吗?还是你想要缩放单元格大小以适应图像? - gnovice
首先非常感谢您。我确实希望单元格的大小适合图像,而不是反过来。我尝试了翻转两侧,就像这样 excelSheet.Range('B2').Height = excelSheet.Shapes.Item(1).Height;。我会尝试找到一个解决方法。 - havakok
@havakok:我更新了答案,使单元格大小适应图像,但是它并没有完全正确地获取列宽。我认为这是Excel的一个更大的问题,因为似乎没有一个好的、明确定义的方法来绘制字符宽度和点/英寸宽度之间的平行线。 - gnovice

3
我借鉴了来自 gnovice答案 中的一些代码。它对我编写这个答案非常有帮助。
下面是一个可行的示例,用于将 peppers.png 插入到单元格 B2 中:
im=imread('peppers.png');
imshow(im);

dpi = get(groot, 'ScreenPixelsPerInch');  % Get screen dpi
print(gcf, sprintf('-r%d', dpi), ...      % Print the figure at the screen resolution
      '-clipboard', '-dbitmap');          %   to the clipboard as a bitmap

excel = actxserver('Excel.Application');  % Create server object
excelWorkbook = excel.Workbooks.Add(1);   % Add a workbook
excelSheet = excel.ActiveSheet;           % Get the active sheet
excelSheet.Range('B2').PasteSpecial();    % Paste from clipboard (top left corner
                                          %   of image will be in the cell 'B2')   
%%%%%%%%%%%%%%%% My contribution %%%%%%%%%%%%%%%%
excelSheet.Shapes.Item(1).LockAspectRatio='msoFalse';            %Unlocking aspect ratio
excelSheet.Shapes.Item(1).Width=excelSheet.Range('B2').Width;    %Adjusting width
excelSheet.Shapes.Item(1).Height=excelSheet.Range('B2').Height;  %Adjusting height
%Uncomment the next line if you want the cell to keep the image fit in its particular 
%cell even if the size of the cell is changed later
% excelSheet.Shapes.Item(1).Placement='xlMoveandSize';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

excelWorkbook.SaveAs('figtest.xlsx');     % Save workbook to a file
excelWorkbook.Close();                    % Close workbook
excel.Quit();                             % Quit server
excel.delete();                           % Delete server object

输出:

输出


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接