Problem displaying image with alpha

Hi,
I'm having some problems displaying an image with alpha. Here's what I have

// get the image bits from an handle
IntPtr imgBits = GetSurfaceBits(m_surfaceId);
// create a new bitmap from these bits
m_bmp = new Bitmap(512, 512, 4 * 512, PixelFormat.Format32bppPArgb, imgBits);

To display it:
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = e.Graphics)
{
// clears the panel to blue
g.Clear(Color.CornflowerBlue);
// this doesn't do anything
if (m_bmp != null)
g.DrawImage(m_bmp, 0, 0, m_bmp.Width, m_bmp.Height);
}
}

I'll just get a blue panel when doing this.

The bitmap is correct because if I do:
m_bmp.Save("test.png", ImageFormat.Png);

the image gets saved correctly when opened in another program, although if I try to load it in my code and display it, I'll get the same result (a blue panel). Another thing I discovered is that if I save the image as a jpg and then load it, it gets displayed correctly.

My guess is that it has something to do with the alpha but can't figure what it is. I'd appreciate if someone gives me some hints on how to solve this.

Thank you.



Answer this question

Problem displaying image with alpha

  • RibTickler

    If you create the bitmap after the paint event occurs the image is not displayed until another paint event occurs. Try adding

    panel1.Invalidate();

    after

    m_bmp = new Bitmap...

    line.

    And a small note:

    you don't need to use "using" for the Graphics object from the PaintEventArgs because you did not create that object. It's the framework job to dispose it.


  • No Progress

    Hi Mike,
    did you receive the e-mail I sent you Did you check anything that I was missing


    Here's the code that I sent Mike, if someone has any idea of what's going on. Just a simple sample with a panel inside a form:

    namespace Sample
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();

                m_bmp = (Bitmap)Bitmap.FromFile("test.png");
            }

            private Bitmap m_bmp;

            private void panel1_Paint(object sender, PaintEventArgs e)
            {
                e.Graphics.DrawImage(m_bmp, 0, 0);
            }
        }
    }

    The problem is that if I try to open a png with alpha, it doesn't get displayed on the panel but if I try a jpg or even a png without alpha, it's displayed.
    I tried different png's and some open but mine don't, you can find mine that doesn't work here:
    http://n0n4m3.gamedev-pt.net/test.png

    Thank you.


  • Michael J Brown

    I told you way the JPG displays properly, JPG does not support an alpha channel so when you save to JPG all the transparency is discarded. It's the GetSurfaceBits that returns you a completly transparent image.


  • Kurt Biesemans

    I've got the Sample and looked at it. Your PNG image is completly transparent ! . That's way it does not display and that's why the JPG works, when saving to JPG the alpha channel is lost.

    I checked if the Bitmap constructor doesn't ignore the alpha channel and it does not so the problem is in the way you retreive those bitmap bits.


  • Vic1234

    Humm.. you're both right, the image is appears "blank" in several programs. I was "lucky" to use one program that opened the image correctly (www.irfanview.com).

    The image was saved from an array:
    IntPtr nmBits = GetSurfaceBits(m_nmSurface);
    m_bmp = new Bitmap(512, 512, 4 * 512, PixelFormat.Format32bppArgb, nmBits);
    m_bmp.Save("test.png", ImageFormat.Png);
    m_bmp.Save("test.jpg", ImageFormat.Jpeg);

    So I must be doing something wrong saving the image because the .jpg and .png files were saved just like I put above and only the png appears "blank".


  • da Vinci

    Well, that should be Argb. The sample here is with PArgb because I was testing it and then I forgot to change back to Argb but the correct is Argb and I changed it back to that.

    I even tried it now using BitBlt:

    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern bool BitBlt(IntPtr obj, int xDest, int yDest, int width, int height, IntPtr objSource, int xSrc, int ySrc, RasterOperations rasterOp);

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
    Graphics g = e.Graphics;
    g.Clear(Color.CornflowerBlue);

    if (m_bmp != null)
    {
    //g.DrawImage(m_bmp, 20, 20, m_bmp.Width, m_bmp.Height);

    Graphics gr = Graphics.FromImage(m_bmp);
    IntPtr hdc = g.GetHdc();
    IntPtr memdc = gr.GetHdc();

    BitBlt(hdc, 0, 0, 512, 512, memdc, 0, 0, RasterOperations.SRCCOPY);

    g.ReleaseHdc(hdc);
    gr.ReleaseHdc(memdc);
    }
    }


    The result was a black rectangle.


  • RaimondB

    "Hi Mike,
    did you receive the e-mail I sent you Did you check anything that I was missing
    "

    Didn't you see my answer above


  • slesniak123

    I just had a look at that test.png that you linked to and as far as I can tell, it is completely blank / transparent. (I used Firefox 2.0 and IE 7.0)
    I think there is something wrong with the generation of the pngs rather than the code that displays them.

    Regards
    Jero


  • Faraz_Ahmed

    Hmm... this is really odd. I notice that you are using PArgb format. Are you sure that the image bits is in this format and not Argb Altough I don't see how saving to a png works correctly but displaying not.


  • anisk

    I forced the onpaint by doing what you suggested but it didn't work. I already had tested this, even manually by moving the window outside the screen and then inside again.

    Thank you for the note about "using", I copied from another sample where I had CreateGraphics instead of using the graphics instance passed as argument, and didn't notice that the "using" wasn't needed anymore.


  • sqlduck

    Sorry about that, I didn't notice your other post  Irfanview tricked me because it displays the image not taking the alpha channel.

    Thank you, I'll look into it


    Edit: Just to let you know that it was indeed the alpha channel all 0's. It was dumb of my part because I then remembered that I had this problem in the past with Irfan view since the program ignores the alpha channel.

    Thank you again and sorry for my dumbness


  • GSK_phili

    I doubt BitBlt can work because it does not know about alpha channels like most of the GDI.

    I'm out of ideas about why this does not work . Try creating a Graphics from that image and draw something to it. See if at least the drawing shows up. Eventually you can try sending the png file to me so I take a look at the bitmap bits (see my profile for a mail address).


  • Problem displaying image with alpha