With this article I'll try to show how to use .Net GDI+ APIs to combine at runtime physical and virtual images.
There's abundance of help requests, in various forums, about how-to overlay multiple images exploiting .Net tools, I think that the following example could be helpful and clarifying.
As usual let's define a real world scenario to contextualize the theoretical stuff:
- goal
create an image to visualize, using the "classical" five stars, a variable rating between 0 and 5 (double type values)
- instruments
C#, GDI+ and Adobe® Photoshop, or similar (used to create base images)
The idea is to assemble a sandwich triple-layered image.
- On the lowest level we put a background image which will act as a placeholder for the "switched-off" stars. The following image is
exactly the one used in this blog:

- on the intermediate level we will draw a golden rectangle of variable width, depending on the rating value;
- on the top level we set a masked and beveled - for aesthetical purposals - image:

Let's dive into the C# code:
float rating = Convert.ToSingle(Request.QueryString["Rating"], System.Globalization.CultureInfo.InvariantCulture)/5F;
Pacem.Drawing.Image pacemimg = new Pacem.Drawing.Image(Server.MapPath("~/Images/CMerighi/Rating_Lower.png"));
Bitmap rect = new Bitmap(pacemimg.Width, pacemimg.Height);
Graphics graph = Graphics.FromImage(rect);
graph.FillRectangle(Brushes.Gold, new RectangleF(0F, 0F, ((float)pacemimg.Width)*rating, (float)pacemimg.Height));
pacemimg.OverlayImage(rect, Pacem.Drawing.VerticalAnchor.Top, Pacem.Drawing.HorizontalAnchor.Left);
pacemimg.OverlayImage(Server.MapPath("~/Images/CMerighi/Rating_Upper.png"), Pacem.Drawing.VerticalAnchor.Top, Pacem.Drawing.HorizontalAnchor.Left);
rect.Dispose(); graph.Dispose();
Response.ContentType = "image/png";
pacemimg.Flush(Response.OutputStream, "image/png");
pacemimg.Dispose();
Pacem.Drawing.Image is a class I developed myself to manipulate images.
It contains scaling, canvas resizing and - above all -
color manipulation methods Photoshop-style with algorithms that render results extremely close to those of the Adobe® software.
If you know something better please let me know.
Now we go in depth into a form of the - overloaded - method OverlayImage showing how it works. Here's the code:
public void OverlayImage(
System.Drawing.Image bmp,
VerticalAnchor vAnchor,
HorizontalAnchor hAnchor
)
{
Graphics graph = Graphics.FromImage(bmp);
int x, y;
double W, w, H, h;
W = (double)_Bitmap.Width; H = (double)_Bitmap.Height;
w = (double)bmp.Width; h = (double)bmp.Height;
switch (vAnchor)
{
case VerticalAnchor.Middle:
y = (int)((H - h) / 2);
break;
case VerticalAnchor.Bottom:
y = _Bitmap.Height - bmp.Height;
break;
default:
y = 0;
}
switch (hAnchor)
{
case HorizontalAnchor.Center:
x = (int)((W - w) / 2);
break;
case HorizontalAnchor.Right:
x = _Bitmap.Width - bmp.Width;
break;
default:
x = 0;
}
Rectangle destR = new Rectangle(x, y, bmp.Width, bmp.Height);
Bitmap _Bmp = new Bitmap(_Bitmap.Width, _Bitmap.Height);
Graphics _Graph = Graphics.FromImage(_Bmp);
_Graph.DrawImage(_Bitmap, 0, 0, _Bitmap.Width, _Bitmap.Height);
_Graph.DrawImage(bmp, destR, new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
_Bitmap = _Bmp;
_Graphics = Graphics.FromImage(_Bitmap);
bmp.Dispose(); graph.Dispose(); _Graph.Dispose();
}
That's it.
Take care. Bye.
Feedbacks
no feedbacks yet.