Re: Create Bitmap image from Outlook Category colour

Tech-Archive recommends: Fix windows errors by optimizing your registry



The speed difference could be partly due to changing the mask. Any interaction with COM will have speed penalties for managed code.

If the mask is being reused for every switch I'd get it once and cache it. Or even cache a few masks. That would shave a little time. So would getting the category properties and passing the values instead of passing the COM object. Whether that would be noticeable to anything but a timer is another story :)

Thanks for posting your solution, BTW. It's always nice to have sample code available to users of these groups.

--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Professional Programming Outlook 2007.
Reminder Manager, Extended Reminders, Attachment Options.
http://www.slovaktech.com/products.htm


"Dorell" <Dorell@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message news:52DE5338-74AB-4DA6-B378-8ADCDE06EA53@xxxxxxxxxxxxxxxx
Hi Ken

Thanks for the response, I’ve just managed to get this working today. Yes I
had issues with using the 48x48 image because I think it was being converted
to a 16x16 image so some of the detail was lost. I managed to display the
gradient fill colour for the Category by;-converting the category picture
mask to a Graphics object, creating a LinearGradientBrush with the top and
bottom gradient colours and filling the graphic with the Linear Brush. I’ve
put the solution below, it works really well and is identical to the icon
created by Outlook but I do have a slight issue with performance. When I
change Categories the icon is updated immediately which is perfect but I have
a situation when no category is selected and I want to display a blank
category with only a border and no fill colour. I do this by setting the
picture to a category with a white fill colour and a black border and I then
use that same image as the mask which displays the command bar button colour
as the category fill colour. The problem is that sometimes it takes a while
to update (anything up to a second) but it doesn’t when you change between
category colours. It’s not all the time either sometimes it’s instant, I
think it may be to do with changing the mask as when you change between
colours the same mask is used.

Any idea why this could be happening?

In the solution below I iterated through all the pixels to apply the border
as it was faster than using a pen to draw the border. Would the method you
described above be faster than using a LinearGradientBrush?

Thanks
Jason

Category category = Application.Session.Categories[Index];

Bitmap categoryMaskBitmap = MaskGenerator.createCategoryMask();
Bitmap categoryPictureBitmap = PictureConverter.CategoryToBitmap(category,
categoryMaskBitmap);

button.Picture = PictureConverter.ImageToPictureDisp(categoryPictureBitmap);
button.Mask = PictureConverter.ImageToPictureDisp(categoryMaskBitmap);

internal class PictureConverter : AxHost
{
private PictureConverter() : base(String.Empty) { }

public static IPictureDisp ImageToPictureDisp(Image image)
{
return (IPictureDisp)GetIPictureDispFromPicture(image);
}

public static Bitmap CategoryToBitmap(Category category, Bitmap
bitmap)
{
Color categoryBorderColor =
GetColorFromOleColor(category.CategoryBorderColor);
Graphics categoryGraphics = Graphics.FromImage(bitmap);
LinearGradientBrush categoryFillColor = new
LinearGradientBrush(new Point(2, 2), new Point(2, 13),
GetColorFromOleColor(category.CategoryGradientTopColor),
GetColorFromOleColor(category.CategoryGradientBottomColor));
categoryGraphics.FillRectangle(categoryFillColor, 2, 2, 12, 12);
return applyCategoryBorder(bitmap, categoryBorderColor);
}

private static Bitmap applyCategoryBorder(Bitmap bitmap, Color
borderColor)
{
for (int x = 0; x < 16; x++)
{
for (int y = 0; y < 16; y++)
{
if (bitmap.GetPixel(x, y).ToArgb() != -1 &&
isBorderPixel(x, y))
{
bitmap.SetPixel(x, y, borderColor);
}
}
}
return bitmap;
}

private static bool isBorderPixel(int x, int y)
{
switch (x)
{
case 1:
return true;
case 2:
if (y == 2 || y == 13) { return true; }
break;
case 13:
if (y == 2 || y == 13) { return true; }
break;
case 14:
return true;
default:
switch (y)
{
case 1:
return true;
case 14:
return true;
}
break;
}
return false;
}
}


public class MaskGenerator
{
public static Bitmap createCategoryMask()
{
Bitmap bitmap = new Bitmap(16, 16);

for (int x = 0; x < 16; x++)
{
for (int y = 0; y < 16; y++)
{
if (isMaskArea(x, y))
{
bitmap.SetPixel(x, y, Color.Black);
}
else
{
bitmap.SetPixel(x, y, Color.White);
}
}
}
return bitmap;
}

private static bool isMaskArea(int x, int y)
{
switch (x)
{
case 0:
return false;
case 15:
return false;
default:
switch (y)
{
case 0:
return false;
case 15:
return false;
}
break;
}
if (isCornerPixel(x, y))
{
return false;
}
return true;
}

private static bool isCornerPixel(int x, int y)
{
switch (x)
{
case 1:
return isOuterEdge(y);
case 2:
return isInnerEdge(y);
case 13:
return isInnerEdge(y);
case 14:
return isOuterEdge(y);
}
return false;
}

private static bool isInnerEdge(int y)
{
switch (y)
{
case 1:
return true;
case 14:
return true;
}
return false;
}

private static bool isOuterEdge(int y)
{
switch (y)
{
case 1:
return true;
case 2:
return true;
case 13:
return true;
case 14:
return true;
}
return false;
}
}
}


.


Quantcast