开发者

Red points on transparent image

开发者 https://www.devze.com 2022-12-21 12:54 出处:网络
I have one Windows Form with this.BackColor = Color.Red and this.TransparencyKey = Color.Red and there is one PictureBox (png image with transparency corners) on 开发者_如何学Pythonthis form,

I have one Windows Form with

this.BackColor = Color.Red

and

this.TransparencyKey = Color.Red

and there is one PictureBox (png image with transparency corners) on 开发者_如何学Pythonthis form,

PictureBox.SizeMode = Normal.

Then I set SizeMode of PictureBox to StretchImage and get other result:

you can see it here

(sorry, I can put one hyperlink only)

You can see red points/dots, but it is not Color.Red because it is transparency key of form.

I tried to implement transparent form, transparent control to remove these "red" points. Anyways, I would like to ask about my last point - I tried to override "OnPaintBackground" method and when I implemented some like code below:

e.Graphics.FillRectangle(Brushes.Red, ClientRectangle);
TextureBrush brush = ImageHelper.ScaleImage(BackgroundImage, ClientRectangle.Width, ClientRectangle.Height);
e.Graphics.FillRectangle(brush, ClientRectangle);

I saved scaled BitMap to file before putting it to TextureBrush - this png scaled image doesn't contain "red" points, but they were painted on form.

Does somebody have any idea why it happens and tell me some way to solve it.

Best regards.


This happens because GDI+, which is drawing the image, doesn't know that red is becoming transparent.

Therefore, it blends the borders of the image with the red background, creating reddish (but not completely red) pixels which do not become transparent.

To solve this, you'll need to make a layered window.

EDIT:

Use the following native methods:

static class NativeMethods {
    public const int LayeredWindow = 0x80000;//WS_EX_LAYERED

    #region Drawing
    [DllImport("User32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool UpdateLayeredWindow(IntPtr handle, IntPtr screenDc, ref Point windowLocation, ref Size windowSize, IntPtr imageDc, ref Point dcLocation, int colorKey, ref BlendFunction blendInfo, UlwType type);

    [DllImport("gdi32.dll")]
    public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

    [DllImport("User32.dll")]
    public static extern IntPtr GetDC(IntPtr hWnd);

    [DllImport("User32.dll")]
    public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

    [DllImport("gdi32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DeleteDC(IntPtr hdc);

    [DllImport("gdi32.dll")]
    public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

    [DllImport("gdi32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DeleteObject(IntPtr hObject);
    #endregion
}
struct BlendFunction {
    public byte BlendOp;
    public byte BlendFlags;
    public byte SourceConstantAlpha;
    public byte AlphaFormat;
}
enum UlwType : int {
    None = 0,
    ColorKey = 0x00000001,
    Alpha = 0x00000002,
    Opaque = 0x00000004
}

Override the form's CreateParams:

protected override CreateParams CreateParams {
    get {
        CreateParams createParams = base.CreateParams;
        createParams.ExStyle |= NativeMethods.LayeredWindow;
        return createParams;
    }
}

Call the following function in OnShown:

static Point Zero;
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults")]
void UpdateWindow() {
    IntPtr screenDC = NativeMethods.GetDC(IntPtr.Zero);
    IntPtr imageDC = NativeMethods.CreateCompatibleDC(screenDC);
    IntPtr gdiBitmap = IntPtr.Zero;
    IntPtr oldBitmap = IntPtr.Zero;

    try {
        gdiBitmap = image.GetHbitmap(Color.FromArgb(0));                //Get a GDI handle to the image.
        oldBitmap = NativeMethods.SelectObject(imageDC, gdiBitmap);     //Select the image into the DC, and cache the old bitmap.

        Size size = image.Size;                                         //Get the size and location of the form, as integers.
        Point location = this.Location;

        BlendFunction alphaInfo = new BlendFunction { SourceConstantAlpha = 255, AlphaFormat = 1 }; //This struct provides information about the opacity of the form.

        NativeMethods.UpdateLayeredWindow(Handle, screenDC, ref location, ref size, imageDC, ref Zero, 0, ref alphaInfo, UlwType.Alpha);
    } finally {
        NativeMethods.ReleaseDC(IntPtr.Zero, screenDC);                 //Release the Screen's DC.

        if (gdiBitmap != IntPtr.Zero) {                                 //If we got a GDI bitmap,
            NativeMethods.SelectObject(imageDC, oldBitmap);             //Select the old bitmap into the DC
            NativeMethods.DeleteObject(gdiBitmap);                      //Delete the GDI bitmap,
        }
        NativeMethods.DeleteDC(imageDC);                                //And delete the DC.
    }
    Invalidate();
}
0

精彩评论

暂无评论...
验证码 换一张
取 消