2

I am looking how to convert Microsoft.Office.Interop.Word/Excel/PowerPoint.Color to System.Drawing.Color in C#.

I have found the contrary in this forum here or here but I don't find how to convert from Interop Color to System.Drawing.Color.

I have understood that Interop color is expressed in RGB considering:

RGBvalue = Red + 256*Green + 256*256*Blue

but it is not very easy from a RGBvalue to find the value of Red Green Blue (for example if the value is 5652 I don't know how to find Red is 20 and Green is 22).

Do you know a function to convert Microsoft.Office.Interop.Word/Excel/PowerPoint.Color to System.Drawing.Color (or to OLE and then, I know how to convert) ?

Freddlow
  • 167
  • 1
  • 12

1 Answers1

3

This is all much simpler if you look at the data in hexadecimal format. 5652 becomes 0x1614, which is clearly bytes 0x16 and 0x14. Or, 0x16 * 0x100 + 0x14.

The opposite of multiplying with 0x100 should simply be dividing it by 0x100, but to actually cut off the excess, I advise using the AND bit operation.

AND will keep only the bits that are common in both values, so, in binary representation, to keep only the lowest 8 bits, you need to AND it with a value with all 8 bits enabled, which would be 0xFF. The AND between 0x1614 (your "5652" example) and 0xFF, viewed in binary format, would go like this:

00010110 00010100
00000000 11111111
v------AND------v
00000000 00010100

As you see, it effectively cuts off everything higher than the lowest byte, resulting in 00010100b, or 0x14, or 20.


For dividing by multiples of 2, there is another bit operation that is very handy and really efficient: bit shifting. 0x100 is actually '1', shifted up by 8 bits. So to get the original value back, it just needs to be shifted down by 8 bits.


if your colour is B * 0x10000 + G * 0x100 + R, then to reverse it:

public static Color GetColorFromInterop(Int32 val)
{
    // Limit to a value containing only the bits in 0xFF
    Int32 r = val & 0xFF;
    // Shift down by 8 bits (meaning, divide by 0x100), then limit to 0xFF
    Int32 g = (val >> 8) & 0xFF;
    // Shift down by 16 bits (meaning, divide by 0x10000), then limit to 0xFF
    Int32 b = (val >> 16) & 0xFF;
    return Color.FromArgb(r, g, b);
}
Nyerguds
  • 5,360
  • 1
  • 31
  • 63