Office 2007 [and higher] interop: retrieve RGB-color

試著忘記壹切 提交于 2019-12-01 13:23:41

It's second time I have problems with retrieving RGB-colors from office documents. First time it was Excel 2007 .xlsx file format, now it's Word 2010 .docx (still 2007 format though). So after a little search I decided to answer my own question for all those fellows who will have the same trouble.

For more deep explanation and examples I send you to the article which helped me a lot . Since examples used in this article probably will be harder to read for C# developers since they're written on VBA I attached link to my implementation of rgb color retriever.

So. If you open one of the Office program (particularly Excel or Word) you can set color of the most objects, text, background etc. And there's a dialog showed to select it. In Office 2007 or higher you'll see a set of 10 standard colors and set of 60 colors based on theme. If you click on 'More colors..' you'll be able to select color from predetermined color set or from RGB-palette.

The way you've chosen a color from that dialog determines format for storing the color. The property which stores color value is a 32-bit integer where 1st the most significant byte (let's call it FormatByte) is for format specification and the other 24-bit for color value or anything else (let's call these 24-bits ColorValue). Here're possible format specifications:

  • FormatByte == 0x00
    ColorValue is common BGR-value. In C# you can retrieve RGB by ColorTranslator.FromOle(ColorValue);. This format is used when you've selected standard colors, or one of the colors from 'More colors..' dialog (predetermined or palette).

  • FormatByte == 0xFF
    ColorValue will be 0x000000. It's wdColorAutomatic value. It's a contrast color and that's all what I know about it (in my case It always was white for background and black for font). Haven't researched it more.

  • FormatByte == 0x80
    ColorValue will be in range [0x000000, 0x000018]. These colors you can meet in ActiveX controls in a document. It's a system KnownColors (there's a c# superset - System.Drawing.KnownColor which contains that values). If I understood right you can retrieve RGB also by ColorTranslator.FromOle(_color);, where _color is all 32-bit property value, because due to reflected implementation of ColorTranslator.FromOle() it checks if color is from KnownColor enum. But I've never been faced with that values while parsing Office files to approve.

  • FormatByte in range [0xD4, 0xDF]
    In that case you deal with color based on theme. It represents as index of base color and tint or shade shift.

Let's take a deeper look at the last case because there're much more difficulties.
As you see the first half of FormatByte is always 0xD and the other half varies from 0x4 to 0xF. This second half is an index of one of the 10 base colors.

There's a wdThemeColorIndex enumeration in Word for that index and it can be translated to more basic Office msoThemeColorSchemeIndex enumeration (it's placed in Microsoft.Office.Core.dll which can be linked from tabPage .COM as Microsoft Office XX.0 Object Library where XX.0 - version of Office). You can take a look to article linked above for the translation sheet or VBA function or to my implementation to C# method. From this msoThemeColorSchemeIndex we can obtain RGB property by ActiveDocument.DocumentTheme.
Then we retrieve tint or shade from ColorValue, translate base color to HSL (hue, saturation, lightness), apply tint or shade to it and translate result back to RGB.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!