Interior.Color属性反转颜色?

我已经写了一段代码,可以让我检索excel工作簿中特定单元格的着色颜色。 通过使用MATLAB的actxserver启动一个COM服务器,然后访问该特定Cell对象的内部对象的颜色属性 ,我已经成功地获取了RGB整数值。 然后我得到这个整数的等价RGB三元组,所以我可以稍后在MATLAB中进行绘图。

为了testing我的代码正常工作,我devise了以下testing:我创build了一个名为colorTest.xlsx的Excel工作簿, colorTest.xlsx具有8种不同的颜色:

在这里输入图像描述

然后运行我的MATLAB代码,它提取B列的每个单元格的颜色信息。 我应该得到与同一垂直顺序的颜色和每个颜色的int值和RGB三元组的表格的情节。

然而意外的事发生了! 看看结果:

在这里输入图像说明

请注意,从Color属性获取的整数值并不总是与原始单元格的颜色匹配,对于黑色,白色,绿色和洋红色,整数值是正确的,但对于所有其他颜色,这不是正确的。 例如,您可以看到,对于Excel上的红色,输出int和RGB三元组对应于蓝色。

我已经添加了下面的表格以及我应该得到的正确结果,以供参考:

 Color Int RGB -------- -------- ----- 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 

我使用这个RGB Int Calculator获得了每种颜色的正确的整数值。

如果我们比较这两个表格,我们可以推断出红色和蓝色的通道是颠倒的

代码:

我执行的运行testing的函数叫做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 RGB\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文件夹中的三个私有函数: validpathxlsCleanupopenExcelWorkbook 。 我只是将它们复制到项目文件夹内的一个名为private的文件夹中。

最后,为了从彩色整数中获得RGB三元组,我使用了一个我从网上find的另一个函数改编的函数 。

这里是我的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 

我试图从这个方面做出一些理解,但我真的不知道发生了什么。 我做了一些研究,没有太多的运气,但这篇文章和这个post引起了我的注意。 也许这跟我的问题有关。

那么Interior.Color属性是否真的颠倒了颜色?

如果是这样的话,我应该认为这是正常的行为还是这是一个错误?


链接下载:

我已经将整个项目打包在一个.zip文件中并上传了,所以你可以马上在你的机器上运行这个testing。 下载文件并解压。

getCellColor.zip

这里没有“正确”或“错误”,Matlab和Excel只是对颜色进行不同的编码。 您需要在代码中说明这一点。

我可以find一个官方源最接近这个MSDN文章,大约一半下来看到“蓝色”编码的例子,

MSDN文章

以下示例将选定单元格的内部设置为蓝色。 Selection.Interior.Color = 16711680
Selection.Interior.Color =&HFF0000
Selection.Interior.Color =&O77600000
Selection.Interior.Color = RGB(0,0,255)

我的第一个想法是检查通道顺序RGB与BGR。

你可以通过使用typecast来简化int2rgb函数。 以下是使用您发布的值的示例:

 clrs = [0; 16777215; 16711680; 65280; 255; 65535; 16711935; 16776960] for i=1:numel(clrs) bgra = typecast(int32(clrs(i)), 'uint8') end 

输出:

 clrs = 0 16777215 16711680 65280 255 65535 16711935 16776960 bgra = 0 0 0 0 bgra = 255 255 255 0 bgra = 0 0 255 0 bgra = 0 255 0 0 bgra = 255 0 0 0 bgra = 255 255 0 0 bgra = 255 0 255 0 bgra = 0 255 255 0 

你的int2rgb方法反转R和B.replace它们,你会得到正确的转换。 Interior.Color属性使用惯例,其中R是最不重要的,而您使用的FileExchange函数使用相反的约定。

从int转换为RGB:

 B = floor(colorInt / (256*256)); G = floor((colorInt - B*256*256)/256); R = colorInt - B*256*256 - G*256; colorRGB = [RGB]; 

从RGB转换为int:

 colorInt = colorRGB * [1 256 256*256]'; 

从MSDN文章 RGB颜色模型:

RGB颜色模型用于指定颜色。 该模型以0到255的比例指定红色,绿色和蓝色的强度,0(零)表示最小强度。 通过使用以下公式将三种颜色的设置转换为单个整数值:

RGB值=红+(绿* 256)+(蓝* 256 * 256)

正如Chris Neilsen的回答所暗示的那样 ,在颜色编码方面没有“正确的”或“错误的”。 微软已经select了这种特定的方式来编码颜色的原因只有他们知道,我应该坚持下去。

所以我得到的RGB值是完全正确的。

在下表中,我将MSDN文章中提供的RGB值包含在我在MATLAB中获得的值旁边,它们是完美匹配的。

 Color Int RGB values from MSDN -------- -------- -------- Black 0 0 White 16777215 16777215 Red 255 255 Green 65280 65280 Blue 16711680 16711680 Cyan 16776960 16776960 Magenta 16711935 16711935 Yellow 65535 65535