Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 透明图像上的红点_C#_Winforms_Transparent - Fatal编程技术网

C# 透明图像上的红点

C# 透明图像上的红点,c#,winforms,transparent,C#,Winforms,Transparent,我有一张Windows窗体和 this.BackColor = Color.Red 及 这个表单上有一个PictureBox(带透明角的png图像) PictureBox.SizeMode = Normal. 然后我将PictureBox的SizeMode设置为StretchImage,并得到其他结果: (对不起,我只能放一个超链接) 你可以看到红色的点,但它不是彩色的。红色是因为它是窗体的透明键 我试图实现透明窗体,透明控件来删除这些“红色”点。 无论如何,我想问一下我的最后一点——我试图

我有一张Windows窗体和

this.BackColor = Color.Red

这个表单上有一个PictureBox(带透明角的png图像)

PictureBox.SizeMode = Normal.
然后我将PictureBox的SizeMode设置为StretchImage,并得到其他结果:

(对不起,我只能放一个超链接)

你可以看到红色的点,但它不是彩色的。红色是因为它是窗体的透明键

我试图实现透明窗体,透明控件来删除这些“红色”点。 无论如何,我想问一下我的最后一点——我试图重写“OnPaintBackground”方法,当我实现下面类似的代码时:

e.Graphics.FillRectangle(Brushes.Red, ClientRectangle);
TextureBrush brush = ImageHelper.ScaleImage(BackgroundImage, ClientRectangle.Width, ClientRectangle.Height);
e.Graphics.FillRectangle(brush, ClientRectangle);
我将缩放后的位图保存到文件中,然后将其放入TextureBrush-此png缩放图像不包含“红色”点,但它们是在表单上绘制的

有人知道为什么会这样吗?告诉我一些解决方法


致以最诚挚的问候。

之所以会出现这种情况,是因为正在绘制图像的GDI+不知道红色正在变得透明

因此,它将图像的边界与红色背景混合,创建不透明的略带红色(但不是完全红色)像素

要解决这个问题,你需要做出一个决定

编辑

使用以下本机方法:

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
}
重写表单的
CreateParams

protected override CreateParams CreateParams {
    get {
        CreateParams createParams = base.CreateParams;
        createParams.ExStyle |= NativeMethods.LayeredWindow;
        return createParams;
    }
}
在显示的
中调用以下函数:

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();
}

TransparencyKey属性已经使用分层窗口来实现它的效果。是的,但它没有按照他需要的方式来实现。他需要提供一个透明图像作为窗口背景。此解决方案不起作用(如我所需:)。我创建了一个新的项目,在上面添加了你的代码,插入了背景图像(它有透明的角落)和拉伸布局,设置背景色和透明键为红色-看到了相同的红点…啊哈。。。您描述了透明窗口的解决方案-很有效,谢谢!!!一个问题:我需要做什么才能看到我以前添加到窗体中的windows控件,因为窗体只显示背景图像。
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();
}