views:

281

answers:

2

So on my site, a user has the ability to create an avatar. It's created by the user selecting from several images; there is a base "skin" image, and png's that overlap that image that depict hair, eyes, mouth, etc.

I cannot save the user's avatar to the project's files, so the user's avatar data is stored in the database, and the png's are overlapped on the fly and displayed to the user.

However, I'd like to have the ability for the user to download their avatar as a jpeg by going to a page.

I have this little example set up that is working correctly:

protected void Page_Load(object sender, EventArgs e)
{
    //User has skin1.png, eyes3.png, and mouth8.png
    Bitmap bit = new Bitmap(System.Drawing.Image.FromFile(Server.MapPath("/images/skin1.png")), 80, 106);

    Response.ContentType = "image/jpeg";
    bit.Save(Response.OutputStream, ImageFormat.Jpeg);
}

But, as you can see, I only have this working for a single image. I'd like to create a bitmap from the multiple png's and output a jpeg.

Can someone help?

+3  A: 

Hi, I think you want to look into Graphics.FromImage when you're overlapping images. I assume there aren't any special effects (simply overlapping and positioning each layer). So you could have something like this:

Graphics gfxAvatar = Graphics.FromImage(bit) //bit is your base image

gfxAvatar.DrawImage(secondLayer, new Point(X,Y)); //Draw secondLayer at X, Y

Continue that with the other layers. (It might be faster to have a Using loop around the initial Graphics gfxAvatar section since there are multiple layers. Then once that's done, you can convert it to a JPG using your bit.Save method.

keyboardP
One thing to be aware of is if GDI+ properly handles/renders transparent PNG images. If it does not then a transparent color would need to be chosen and the image rendered as a transparent bitmap.
Very good point! OP may want to look at http://msdn.microsoft.com/en-us/library/ms172507.aspx
keyboardP
+4  A: 

You can just paint the images on top of each other. The transparency of PNG images are handled correctly, but as JPEG images doesn't have any transparency you would want a background color to draw on.

Remember to be careful to dispose of the Graphics and Bitmap objects properly. They are not even recommended to be used in a web application...

// create image to draw on
using (Bitmap bit = new Bitmap(80, 106)) {
  // fill with background
  bit.Clear(Color.White);
  // images to load
  string[] skins = new string[] { "skin1.png", "eyes3.png", "mouth8.png" };
  // create graphics object for drawing on the bitmap
  using (Graphics g = Graphics.FromImage(bit)) {
    foreach (string skin in skins) {
      // load image
      using (Image skinImage = Image.FromFile(Server.MapPath("/images/" + skin)) {
        // draw image
        g.DrawImage(skinImage, 0, 0, 80, 106);
      }
    }
  }
  Response.ContentType = "image/jpeg";
  bit.Save(Response.OutputStream, ImageFormat.Jpeg);
}
Guffa