2016-02-06 12 views
5

Ich habe einen Code geschrieben, mit dem ich die Schattierungsfarbe einer bestimmten Zelle in einem Arbeitsblatt einer Excel-Arbeitsmappe abrufen kann. Ich habe den RGB-Integer-Wert erfolgreich abgerufen, indem ich einen COM-Server mit MATLAB actxserver gestartet habe und dann auf das Color Property des Interior-Objekts dieses bestimmten Cell Object zugegriffen habe. Dann erhalte ich das äquivalente RGB-Triplet dieser ganzen Zahl, damit ich es später für das Zeichnen in MATLAB verwenden kann.Interior.Color-Eigenschaft invertiert Farben?

Damit mein Code zu testen, funktioniert entwarf ich den folgenden Test: Ich habe eine Excel-Arbeitsmappe colorTest.xlsx mit 8 verschiedenen Farben genannt:

enter image description here

Dann laufe ich meinen MATLAB-Code, der die Extrakte Farbinformationen zu jeder Zelle der B-Spalte. Ich sollte ein Diagramm mit den Farben in der gleichen vertikalen Reihenfolge und eine Tabelle mit dem int-Wert und dem RGB-Triplet jeder Farbe erhalten.

Es passiert jedoch etwas Unerwartetes! Schauen Sie sich die Ergebnisse:

enter image description here

Beachten Sie, dass der ganzzahlige Wert, der von der Farbeigenschaft erhalten wird, nicht immer die Farbe der ursprünglichen Zelle entsprechen, für Schwarz, Weiß, Grün und Magenta die ganzzahligen Werte richtig, aber das gilt nicht für alle anderen Farben. Sie können beispielsweise sehen, dass für die rote Farbe im Excel die Ausgabe int und das RGB-Triplet der blauen Farbe entsprechen.

Ich habe die folgende Tabelle mit den richtigen Ergebnissen habe ich sollte als Referenz erhalten:

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 

ich die richtige ganzzahlige Werte für jede Farbe erhalten this RGB Int Calculator verwenden.

Wenn wir die beiden Tabellen vergleichen, können wir daraus schließen, dass die Rot- und Blau-Kanäle invertiert sind.

Der Code:

Die Funktion, die ich führen Sie den Test auszuführen ist getCellColor genannt. Sehen Sie sich den Code an:

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 

(*) Diese Anweisung ist verantwortlich für die Wiederherstellung der Farb-Ganzzahl.


Anmerkung: Die nächsten beschriebenen Funktionen, verursachen nicht das Problem, dasie nehmen nicht an dem Erhalt der Farb integer (sie sind nur für die Nebenaufgaben verwendet wird). Ich habe diese Informationen nur zur Vollständigkeit hinzugefügt.

Während dieses Prozesses verwende ich drei privaten Funktionen aus dem iofun Ordner, der MATLAB, die sind: validpath, xlsCleanup und openExcelWorkbook. Ich kopierte sie einfach in einen Ordner namens private innerhalb des Projektordners.

Schließlich, um das RGB-Triplet aus der Farbe Integer zu erhalten, verwende ich eine Funktion, die ich aus this other function, die ich im Netz gefunden habe, angepasst habe. Hier

ist der Code für meine int2rgb Funktion:

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 

Ich versuche, ein Gefühl aus dem Spiel zu machen, aber ich habe wirklich keine Ahnung von dem, was geschieht. Ich habe einige Recherchen gemacht, ohne viel Glück, aber this post und this other post hat meine Aufmerksamkeit erregt. Vielleicht hat es etwas mit meinem Problem zu tun.

Also invertiert die Interior.Color-Eigenschaft wirklich Farben?

Wenn dies der Fall ist, sollte ich dies als normales Verhalten betrachten oder ist das ein Fehler?


Link heruntergeladen werden:

Ich habe das gesamte Projekt auf mich .zip Datei gepackt und hochgeladen, so dass Sie diesen Test auf Ihrem Rechner sofort ausgeführt werden können. Laden Sie die Datei herunter und entpacken Sie sie.

getCellColor.zip

+0

Können Sie jetzt Änderungen in der Excel-Palette vornehmen? Ich fand das nützlich. Unglücklicherweise habe ich Matlab nicht, um das selbst zu lösen: [link] (http://www.cpearson.com/excel/colors.aspx) --- Sie ändern die Werte in der Standardpalette, indem Sie das Farben - Array des Arbeitsmappenobjekt Um beispielsweise die Farbe zu ändern, auf die der ColorIndex-Wert 3 verweist, verwenden Sie ==> 'Arbeitsmappen (" SomeBook.xls "). Farben (3) = RGB (0,0,255)' –

+0

Ich habe dieses Problem noch nie gesehen Innenraum.Farbe. Meine Vermutung ist, dass Ihre RGB-Int-Konvertierung rückwärts ist. So konvertiere ich RGB in int, wenn ich Interior.Color: 'longColor = rgbColor * [1 256 256 * 256] ';'. Funktioniert für jede Farbe, die Sie mögen. – buzjwa

+0

Ich habe jetzt Ihre 'int2rgb' Methode überprüft. Es invertiert tatsächlich R und B. – buzjwa

Antwort

2

Vom MSDN article auf RGB-Farbmodell:

Das RGB-Farbmodell wird zum Spezifizieren von Farben verwendet. Dieses Modell spezifiziert die Intensität von Rot, Grün und Blau auf einer Skala von 0 bis 255, wobei 0 (Null) die minimale Intensität angibt. Die Einstellungen von die drei Farben zu einem einzigen Integer-Wert umgewandelt, indem Sie diese Formel:

RGB-Wert = Rot + (grün * 256) + (Blau * 256 * 256)

Wie wurde in chris neilsen answer vorgeschlagen, gibt es keine "richtig" oder "falsch" in Bezug auf Farbcodierung. Microsoft hat diesen speziellen Weg gewählt, Farben aus nur ihnen bekannten Gründen zu kodieren, und ich sollte dabei bleiben.

Also die RGB-Werte, die ich bekomme, sind völlig richtig.

In der folgenden Tabelle habe ich die RGB-Werte, die im MSDN-Artikel enthalten sind, neben denen, die ich in MATLAB erhalte, eingefügt, und sie sind eine perfekte Übereinstimmung.

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 
3

Ihre int2rgb Methode invertiert R und B. sie ersetzen, und Sie werden die richtige Umwandlung zu erhalten. Die Interior.Color-Eigenschaft verwendet die Konvention, wobei R die niedrigste Bedeutung hat, während die von Ihnen verwendete FileExchange-Funktion die entgegengesetzte Konvention verwendet.

Um von int zu RGB zu konvertieren:

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

von RGB zu konvertieren int: der Kanal-Reihenfolge RGB vs. BGR

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

Mein erster Gedanke ist, überprüfen.

Sie könnten diese int2rgb Funktion wahrscheinlich vereinfachen, indem Sie stattdessen typecast verwenden. Hier ist ein Beispiel mit den Werten Sie auf dem Laufenden:

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

Der Ausgang:

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 
5

Es gibt kein „richtig“ oder „falsch“ hier, Matlab und Excel kodieren nur Farbe unterschiedlich. Sie müssen dies in Ihrem Code berücksichtigen.

Der nächstgelegene ich zu einer offiziellen Quelle finden kann, ist diese MSDN-Artikel, etwa auf halbem Weg nach unten das Beispiel der Codierung von „blau“

MSDN article

die folgenden Beispiele das Innere eines sehen Auswahl der Zellen in der Farbe Blau. Selection.Interior.Color = 16711680
Selection.Interior.Farbe = & HFF0000
Selection.Interior.Color = & O77600000
Selection.Interior.Color = RGB (0, 0, 255)

+0

Das ist überraschend. Ich dachte, dass die Farbkodierung für alle gleich ist, wie eine Art Standard. – codeaviator

Verwandte Themen