0

In my application I am merging different image files which would be markers for my google maps application. Here is how the marker looks afterwardsenter image description here

This is how I achieve it

foreach (ImageInfo imageInfo in files)
{

System.Drawing.Bitmap image = new System.Drawing.Bitmap(imageInfo.path);

g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;

if (imageInfo.position == ImagePosition.Base)
{
    if (imageInfo.isZoomed)
        isZoomed = true;
    g.DrawImage(image, new System.Drawing.Rectangle(0, 0, image.Width, image.Height));
}
else if (imageInfo.position == ImagePosition.TopRight)
{
    g.DrawImage(image, new System.Drawing.Rectangle(image.Width + 70, 10, 200, 200));
}

else if (imageInfo.position == ImagePosition.TopLeft)
{
    g.DrawImage(image, new System.Drawing.Rectangle(10, -10, 200, 200));
}

else if (imageInfo.position == ImagePosition.BottomRight)
{
    g.DrawImage(image, new System.Drawing.Rectangle(image.Width + 70, image.Height - 40, 200, 200));
}

}

The only thing I am missing is a shadow around the marker, here you can see what I am talking about enter image description here. There is a slight shadow around the marker in the above image.

Anyone knows how to achieve it?

mohsinali1317
  • 4,255
  • 9
  • 46
  • 85
  • no its a console application. – mohsinali1317 Oct 31 '16 at 13:38
  • 1
    Aha, a console application. I've added that tag for you, so you'll get more attention from people who might be able to help. – 15ee8f99-57ff-4f92-890c-b56153 Oct 31 '16 at 13:39
  • thanks mate. looking forward to it. – mohsinali1317 Oct 31 '16 at 13:41
  • 2
    You should consider adding GDI+ as tag, since this hasn't anything to do with either WinForm or Console. It's simply GDI+. I don't really see what you mean by shadow tho'. – SharpShade Oct 31 '16 at 13:41
  • 1
    Possible duplicate of [Algorithm for fast Drop shadow in GDI+](http://stackoverflow.com/questions/7364026/algorithm-for-fast-drop-shadow-in-gdi) – Clint Oct 31 '16 at 13:42
  • 3
    Have you considered drawing it with a Visual / RenderTargetBitmap instead? (WPF) you could just use a DropShadowEffect there. – Manfred Radlwimmer Oct 31 '16 at 13:46
  • how is that the duplicate of that? I am not sure and I can't understand that question and the answer. I guess my issue is way to simpler. – mohsinali1317 Oct 31 '16 at 13:46
  • I really can't see any shadow in the two images. For a 1-2 pixel pseudo-shadow you could do this: enlarge the image b 1-2 then by 3-4 pixels and use color matrix to make the resulting bitmaps darker and a little darker. Then draw all 3 centered and on top of each other, lighter dark frist, then darkest, then original. Assuming of course they are pngs with tranparent outside. – TaW Oct 31 '16 at 13:46
  • @ManfredRadlwimmer no I haven't done that but my application is console not windows form. – mohsinali1317 Oct 31 '16 at 13:47
  • 1
    You don't necessarily need a WinForm or WPF project to use WPF elements. I guess you could indeed use a Visual and a RenderTargetBitmap for that as @ManfredRadlwimmer said. Might need to set `[STAThread]` on your *Main*-method, though. But since you're using circular icons, you could also simply draw an arc around them using their width/height as diameter. – SharpShade Oct 31 '16 at 13:48
  • 1
    @ChaudhryMohsinAli It's a console Application but you are using the old (WinForms) `System.Drawing` namespace. You could use `System.Windows.Media.Imaging` instead. – Manfred Radlwimmer Oct 31 '16 at 13:49
  • @ManfredRadlwimmer can I get an example or something? – mohsinali1317 Oct 31 '16 at 13:54
  • 1
    [Use RQDQ's answer](http://stackoverflow.com/questions/5189139/how-to-render-a-wpf-usercontrol-to-a-bitmap-without-creating-a-window) and use the `Image` Visual in `System.Windows.Controls`. Apply the *DropShadowEffect* on it and you're done ;) – SharpShade Oct 31 '16 at 14:00

1 Answers1

0

This is how I solved it finally

Bitmap shadow = (Bitmap)finalImage.Clone();

for (int y = 0; y < shadow.Height; y++) {

for (int x = 0; x < shadow.Width; x++)
{
    var color = shadow.GetPixel(x, y);

    color = Color.FromArgb((int)((double)color.A * 0.2), 0, 0, 0);

    shadow.SetPixel(x, y, color);

}
}

var finalComposite = new Bitmap(finalImage.Width, finalImage.Height, PixelFormat.Format32bppArgb);

using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(finalComposite))
{
g.Transform = new Matrix(new Rectangle(0, 0, shadow.Width, shadow.Height), new Point[]{
    new Point(50,20),
    new Point(width+50, 20),
    new Point(0, height)
});

g.DrawImageUnscaled(shadow, new Point(0, 0));

g.ResetTransform();
g.DrawImageUnscaled(finalImage, new Point(0, 0));
}
mohsinali1317
  • 4,255
  • 9
  • 46
  • 85
  • 1
    GetPixel/SetPixel are horribly slow, but if that doesn't bother you - fine. Otherwise you can achieve the same thing by passing a suitable ColorMatrix to the DrawImage call. – Dan Byström Oct 31 '16 at 21:06