簡體   English   中英

Interior.Color屬性反轉顏色?

[英]Interior.Color Property inverts colors?

我編寫了一段代碼,允許我檢索excel工作簿中的特定單元格的着色顏色。 我已成功檢索RGB整數值,方法是使用MATLAB的actxserver啟動COM服務器,然后訪問該特定Cell對象的Interior Object的Color屬性 然后我獲得該整數的等效RGB三元組,因此我可以稍后在MATLAB中使用它進行繪圖。

為了測試我的代碼是否正常工作,我設計了以下測試:我創建了一個名為colorTest.xlsx的Excel工作簿, colorTest.xlsx有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

我使用RGB Int計算器為每種顏色獲得了正確的整數值。

如果我們比較兩個表,我們可以推斷紅色和藍色通道是反轉的

代碼:

我執行以運行測試的函數稱為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文件夾中的三個私有函數,它們是: validpathxlsCleanupopenExcelWorkbook 我只是將它們復制到項目文件夾中名為private的文件夾中。

最后,為了從顏色整數中獲取RGB三元組,我使用了一個函數,我從網上找到的其他函數改編而來。

這是我的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

我試圖弄清楚這一點,但我真的不知道發生了什么。 我做了一些研究,沒有太多運氣,但這篇文章另一篇文章引起了我的注意。 也許它與我的問題有關。

那么Interior.Color屬性是否真的顛倒了顏色?

如果是這種情況,我應該將此視為正常行為還是這是一個錯誤?


鏈接下載:

我已將整個項目打包到.zip文件上並上傳,因此您可以立即在您的計算機上運行此測試。 下載文件並解壓縮。

getCellColor.zip

這里沒有“正確”或“錯誤”,Matlab和Excel只是對顏色進行不同的編碼。 您需要在代碼中考慮到這一點。

我能找到的最接近官方來源的是這篇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.替換它們,你將得到正確的轉換。 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 = [R G B];

要從RGB轉換為int:

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

從關於RGB顏色模型的MSDN文章

RGB顏色模型用於指定顏色。 此模型以0到255的等級指定紅色,綠色和藍色的強度,0(零)表示最小強度。 使用以下公式將三種顏色的設置轉換為單個整數值:

RGB值=紅色+(綠色* 256)+(藍色* 256 * 256)

正如在chris neilsen的回答中所建議的那樣 ,在顏色編碼方面沒有“正確”或“錯誤”。 微軟選擇這種特殊的方式來編碼顏色只是因為他們知道的原因,我應該堅持下去。

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

在下表中,我已經在MSDN文章中提供了我在MATLAB中獲得的RGB值,它們是完美的匹配。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM