views:

330

answers:

2

I'm writing a CSS sprite engine in C#, however I'm having a few issues. I create the master image, set all the properties to that then iterate the sprites and draw those to the master image. However when I come to save the master image it only appears to be just the empty master image with transparent background and none of the sprites. I'm very confused at where I'm going wrong.

The code I'm using is:

    // Work out the width/height required
    int max_width = 0;
    int max_height = 0;

    foreach(SpriteInformation sprite in sprites) {
        if (max_width < (sprite.Left + greatest_width)) max_width = sprite.Left + greatest_width;
        if (max_height < (sprite.Top + greatest_height)) max_height = sprite.Top + greatest_height;
    }

    // Create new master bitmap
    Bitmap bitmap = new Bitmap(max_width,max_height,PixelFormat.Format32bppArgb);
    Graphics graphics = Graphics.FromImage(bitmap);

    // Set background color
    SolidBrush brush;

    if (cbxBackground.Checked) {
        if (txtColor.Text == "") {
            brush = new SolidBrush(Color.Black);
        } else {
            brush = new SolidBrush(pnlColor.BackColor);
        }
    } else {
        if (txtColor.Text == "") {
            brush = new SolidBrush(Color.White);
        } else {
            brush = new SolidBrush(pnlColor.BackColor);
        }
    }

    //graphics.FillRectangle(brush,0,0,bitmap.Width,bitmap.Height);
    bitmap.MakeTransparent(brush.Color);
    graphics.Clear(brush.Color);

    // Copy images into place
    ImageAttributes attr = new ImageAttributes();

    //attr.SetColorKey(brush.Color,brush.Color);

    foreach(SpriteInformation sprite in sprites) {
        Rectangle source = new Rectangle(0,0,sprite.Width,sprite.Height);
        Rectangle dest = new Rectangle(sprite.Left,sprite.Top,sprite.Width,sprite.Height);

        graphics.DrawImage(sprite.Sprite,dest,0,0,sprite.Width,sprite.Height,GraphicsUnit.Pixel,attr);
    }

    // Save image
    string format = ddlFormat.Items[ddlFormat.SelectedIndex].ToString();

    if (format == "PNG") {
        dlgSave.Filter = "PNG Images|*.png|All Files|*.*";
        dlgSave.DefaultExt = ",png";

        if (dlgSave.ShowDialog() == DialogResult.OK) {
            bitmap.Save(dlgSave.FileName,ImageFormat.Png);
        }
    } else if (format == "JPEG") {

    } else {

    }
A: 

You draw to "graphics", but then then you save "bitmap"? I'm not sure if that graphics internally works with your original "bitmap" object...

jishi
That does appear to be the implication in the docs: http://msdn.microsoft.com/en-us/library/system.drawing.graphics.fromimage.aspx
Mike Houston
A: 

What are sprite.Left and Top? If they aren't 0 that may be a problem. I think you have dest and source the wrong way round?

http://msdn.microsoft.com/en-us/library/ms142045.aspx

Try a simpler DrawImage variant if you haven't already. e.g. DrawImage(sprite.Sprite,0,0)

Mike Houston
The sprite.Left/Top gives the coords where to draw the image on the final image. I've tried with DrawImage(sprite.Sprite,0,0) and DrawImage(sprite.Sprite,sprite.Left,sprite.Top) to no avail. I am certain the sprite.Sprite is assigned too because they're just loaded from another PNG and not touched.
Lloyd
:/ I see now. When you are calculating the maximum size of the bitmap, why do you use greatestwidth/height instead of the actual sprite size? Just grasping at straws here I'm afraid. I would try resetting all of those offsets to 0 and rendering onto a large image, just to make sure it's rendering into the area of the target image you think it is. Then you can add the offsets back in.
Mike Houston
Yeh I'll try that next. The greatest width/height is basically the furthest offset+n required for a sprite so that I know how big the image is going to have to be.
Lloyd
Nah that didn't work either! Merde. :(
Lloyd
OK got it working by moving the MakeTransparent, the issue is now the alpha of the source sprites does not seem to keep.
Lloyd