【发布时间】:2016-05-16 11:03:39
【问题描述】:
我编写了一段代码,允许我检索 Excel 工作簿工作表中特定单元格的阴影颜色。通过使用 MATLAB 的actxserver 启动 COM 服务器,然后访问该特定单元对象的内部对象的Color Property,我已成功检索 RGB 整数值。然后我获得了该整数的等效 RGB 三元组,以便稍后在 MATLAB 中使用它进行绘图。
为了测试我的代码是否正常工作,我设计了以下测试:我创建了一个名为 colorTest.xlsx 的 Excel 工作簿,有 8 种不同颜色:
然后我运行我的 MATLAB 代码,该代码提取 B 列的每个单元格的颜色信息。我应该得到一个具有相同垂直顺序的颜色的图和一个具有 int 值和每种颜色的 RGB 三元组的表格。
然而,意想不到的事情发生了!查看结果:
请注意,从 Color 属性获得的整数值并不总是与原始单元格的颜色相匹配,对于黑色、白色、绿色和洋红色,整数值是正确的,但对于所有其他颜色来说并非如此.例如,您可以看到,对于 Excel 上的红色,输出的 int 和 RGB 三元组对应于蓝色。
我已经添加了下表,其中包含我应该得到的正确结果,以供参考:
Color Int R G B
-------- -------- -----
Black 0 0 0 0
White 16777215 1 1 1
Red 16711680 1 0 0
Green 65280 0 1 0
Blue 255 0 0 1
Cyan 65535 0 1 1
Magenta 16711935 1 0 1
Yellow 16776960 1 1 0
我使用this RGB Int Calculator 获得了每种颜色的正确整数值。
如果我们比较两张表,我们可以推断出红色和蓝色通道是倒置的。
代码:
我为运行测试而执行的函数称为getCellColor。看看代码:
function getCellColor()
clear all;
clc;
% Excel
filename = 'colorTest.xlsx';
% Start Excel as ActiveX server process on local host
Excel = actxserver('Excel.Application');
% Handle requested Excel workbook filename
path = validpath(filename);
% Cleanup tasks upon function completion
cleanUp = onCleanup(@()xlsCleanup(Excel, path));
% Open Excel workbook.
readOnly = true;
[~, workbookHandle] = openExcelWorkbook (Excel, path, readOnly);
% Initialise worksheets object
workSheets = workbookHandle.Worksheets;
% Get the sheet object (sheet #1)
sheet = get(workSheets,'item',1);
% Print table headers
fprintf('Color \t Int \t R G B\n');
fprintf('--------\t --------\t -----\n');
% Create figure
figure;
hold on;
% Loop through every color on the Excel file
for row = 1:8
% Get the cell object with name of color
cell = get(sheet, 'Cells', row, 1);
cName = cell.value;
% Get the cell object with colored background
cell = get(sheet, 'Cells', row, 2);
% Get the interior object
interior = cell.Interior;
% Get the color integer property
cInt = get(interior, 'Color'); % <-- Pay special attention here(*)
% Get the RGB triplet from its integer value
cRGB = int2rgb(cInt);
% Plot the color
patch([0 0 1 1], [8-row 9-row 9-row 8-row], cRGB);
% Print row with color data
fprintf('%-8s\t %8d\t %d %d %d\n', cName, cInt, cRGB);
end
% Turn off axes
set(findobj(gcf, 'type','axes'), 'Visible','off')
end
(*) 该指令负责恢复颜色整数。
注意:后面介绍的函数,不会引起问题,因为它们不参与颜色整数的获取(它们只用于次要任务)。我包含此信息只是为了完整性。
在此过程中,我使用了 MATLAB 的 iofun 文件夹中的三个 private 函数,它们是:validpath、xlsCleanup 和 openExcelWorkbook。我只是将它们复制到项目文件夹内名为 private 的文件夹中。
最后,为了从颜色整数中获取 RGB 三元组,我使用了一个我从网上找到的this other function 改编的函数。
这是我的int2rgb 函数的代码:
function[RGB] = int2rgb(colorInt)
% Returns RGB triplet of an RGB integer.
if colorInt > 16777215 || colorInt < 0
error ('Invalid int value. Valid range: 0 <= value <= 16777215')
end
R = floor(colorInt / (256*256));
G = floor((colorInt - R*256*256)/256);
B = colorInt - R*256*256 - G*256;
RGB = [R, G, B]/255;
end
我试图对此有所了解,但我真的不知道发生了什么。我做了一些研究,运气不佳,但this post 和this other post 引起了我的注意。可能和我的问题有关。
那么 Interior.Color 属性真的会反转颜色吗?
如果是这种情况,我应该将其视为正常行为还是错误?
下载链接:
我已将整个项目打包成一个 .zip 文件并上传,因此您可以立即在您的机器上运行此测试。下载文件并解压。
【问题讨论】:
-
您现在可以在 Excel 调色板中进行更改吗?我发现这可能很有用。不幸的是,我自己没有 Matlab 来解决这个问题:link --- 您可以通过修改 Workbook 对象的 Colors 数组来更改默认调色板中的值。例如,要将 ColorIndex 值 3 引用的颜色更改为蓝色,请使用 ==>
Workbooks("SomeBook.xls").Colors(3) = RGB(0,0,255) -
我从未见过 Interior.Color 的这个问题。我的猜测是你的 RGB-int 转换是倒退的。这就是我在设置 Interior.Color 时将 RGB 转换为 int 的方式:
longColor = rgbColor * [1 256 256*256]';。适用于您喜欢的任何颜色。 -
我现在检查了你的
int2rgb方法。它确实颠倒了 R 和 B。 -
@Naveh 确实,我知道我可以更改我的
int2rgb函数并修复颜色反转,但这不是我要问的(请阅读注释)。问题的根源远在此之前,可能与Excel的颜色编码有关。