Ho scritto un pezzo di codice che mi consente di recuperare il colore di ombreggiatura di una cella specifica all'interno di un foglio di una cartella di lavoro Excel. Ho recuperato con successo il valore intero RGB avviando un server COM utilizzando MATLAB actxserver
e quindi accedendo allo Color Property dell'oggetto interno di quel particolare oggetto cella. Quindi ottengo la tripletta RGB equivalente di quello intero, quindi posso usarla più tardi per tracciare in MATLAB.Interior.Color Proprietà inverte i colori?
Al fine di verificare che il mio codice funziona correttamente ho progettato il seguente test: ho creato una cartella di lavoro di Excel chiamato colorTest.xlsx
con 8 diversi colori:
Poi eseguo il mio codice MATLAB, che estrae il informazioni sul colore su ogni cella della colonna B. Dovrei ottenere una trama con i colori sullo stesso ordine verticale e una tabella con il valore int e la tripletta RGB di ogni colore.
Tuttavia accade qualcosa di inaspettato! Guardate i risultati:
Si noti che il valore intero che si ottiene dalla proprietà di colore non sempre corrisponde al colore della cella originale, per il nero, bianco, verde e magenta i valori interi sono corretto, ma questo non è vero per tutti gli altri colori. Ad esempio, è possibile vedere che per il colore rosso su Excel, l'output int e la terzina RGB corrispondono al colore blu.
Ho aggiunto la seguente tabella con i risultati corretti devo ottenere, per riferimento:
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
ho ottenuti i valori interi corretti per ciascun colore usando this RGB Int Calculator.
Se confrontiamo le due tabelle, possiamo dedurre che i canali Rosso e Blu sono invertiti.
Il codice:
La funzione che eseguo per eseguire il test si chiama getCellColor
. Date un'occhiata al codice:
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
(*) Questa istruzione è responsabile del recupero del numero intero di colori.
Nota: Le funzioni descritte successiva, non causano il problema poiché non prendono parte alla ottenimento del numero intero colore (sono usati soltanto per compiti secondari). Ho incluso queste informazioni solo per completezza.
Durante questo processo io uso tre privati funzioni dalla cartella iofun del MATLAB, che sono: validpath
, xlsCleanup
e openExcelWorkbook
. Li ho semplicemente copiati in una cartella denominata privata all'interno della cartella del progetto.
Infine, per ottenere la terzina RGB dal numero intero di colori, utilizzo una funzione che ho adattato da this other function che ho trovato in rete.
Ecco il codice per la mia funzione 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
Sto cercando di dare un senso di questo, ma io in realtà non hanno alcuna idea di ciò che sta accadendo. Ho fatto qualche ricerca, senza molta fortuna, ma lo this post e lo this other post hanno attirato la mia attenzione. Forse ha qualcosa a che fare con il mio problema.
Così la proprietà Interior.Color inverte realmente i colori?
Se questo è il caso, dovrei considerare questo come comportamento normale o si tratta di un bug?
link per scaricare:
ho imballato l'intero progetto su un file .zip e lo ha caricato, in modo da poter eseguire questo test sulla vostra macchina subito. Scarica il file e decomprimi.
A questo punto è possibile apportare modifiche alla tavolozza di Excel? Ho trovato questo che potrebbe essere utile. Sfortunatamente, non ho Matlab per risolverlo da solo: [link] (http://www.cpearson.com/excel/colors.aspx) --- Si modificano i valori nella tavolozza predefinita modificando l'array Colors del Oggetto cartella di lavoro. Ad esempio, per cambiare il colore referenziato da ColorIndex valore 3 a blu, utilizzare ==> 'Cartelle di lavoro (" SomeBook.xls "). Colori (3) = RGB (0,0,255)' –
Non ho mai visto questo problema con Interior.Color. La mia ipotesi è che la conversione RGB-int sia al contrario. Ecco come convertire RGB in int quando ho impostato Interior.Color: 'longColor = rgbColor * [1 256 256 * 256] ';'. Funziona per qualsiasi colore che ti piace. – buzjwa
Ho controllato il tuo metodo 'int2rgb' ora. In effetti inverte R e B. – buzjwa