C# winforms上具有PictureBox不透明度的透明背景

C# winforms上具有PictureBox不透明度的透明背景,c#,winforms,background,transparent,C#,Winforms,Background,Transparent,我正在尝试实现一个具有透明背景的全屏Windows窗体,并且窗体中有浮动的图像。对于每个图像,都有一个特定的alpha/不透明度 我在其他帖子上找到了几种解决方案,但都不管用。下面是我用来测试不同设置的代码 这段代码创建了一个具有透明背景和2个图像的全屏表单 1英寸(200,0)的矩形,宽度为200,高度为200,红色的alpha/不透明度为200(255为最大alpha/不透明度) 1英寸(0200)的矩形,宽度为200,高度为200,红色,alpha/不透明度为100 使用系统图; 使用

我正在尝试实现一个具有透明背景的全屏Windows窗体,并且窗体中有浮动的图像。对于每个图像,都有一个特定的alpha/不透明度

我在其他帖子上找到了几种解决方案,但都不管用。下面是我用来测试不同设置的代码

这段代码创建了一个具有透明背景和2个图像的全屏表单

  • 1英寸(200,0)的矩形,宽度为200,高度为200,红色的alpha/不透明度为200(255为最大alpha/不透明度)
  • 1英寸(0200)的矩形,宽度为200,高度为200,红色,alpha/不透明度为100
使用系统图;
使用System.Windows.Forms;
使用系统、绘图、成像;
名称空间屏幕查看器
{
公共部分类FormDisplay:Form
{
PaintBackground上受保护的覆盖无效(PaintEventArgs e)
{
如果(真)
根据背景(e);
}
公共窗体显示()
{
初始化组件();
var data1=new{top=0,left=200,width=200,height=200,alpha=200};
var data2=new{top=200,left=0,width=200,height=200,alpha=100};
如果(真)
if(false)
{
设置样式(ControlStyles.SupportsTransparentBackColor,true);
SetStyle(ControlStyles.UserPaint,true);
SetStyle(ControlStyles.OptimizedDoubleBuffer,true);
背景色=颜色。透明;
透明键=背景色;
}否则{
透明键=颜色。品红色;
背景色=颜色。洋红色;
}
PictureBox pbx_1=新PictureBox{AutoSize=true,Dock=DockStyle.None,Visible=true,Location=new Point(data1.left,data1.top)};
位图bmp1=新位图(data1.width,data1.height);
使用(Graphics g=Graphics.FromImage(bmp1)){g.Clear(Color.Red);}
bmp1=SetAlpha(bmp1,data1.alpha);
pbx_1.Image=bmp1;
PictureBox pbx_2=新PictureBox{AutoSize=true,Dock=DockStyle.None,Visible=true,Location=new Point(data2.left,data2.top)};
位图bmp2=新位图(data2.width,data2.height);
使用(Graphics g=Graphics.frommage(bmp2)){g.Clear(Color.Red);}
bmp2=SetAlpha(bmp2,data2.alpha);
pbx_2.Image=bmp2;
bmp1.Save(“test1.Png”,ImageFormat.Png);
bmp2.Save(“test2.Png”,ImageFormat.Png);
添加(pbx_1);
添加(pbx_2);
}
静态位图SetAlpha(位图bmpIn,int alpha)
{
位图bmpOut=新位图(bmpIn.Width、bmpIn.Height);
浮动a=α/255f;
矩形r=新矩形(0,0,bmpIn.Width,bmpIn.Height);
浮动[][]矩阵项={
新浮点[]{1,0,0,0,0},
新浮点[]{0,1,0,0,0},
新浮点[]{0,0,1,0,0},
新浮点[]{0,0,0,a,0},
新的浮点[]{0,0,0,0,1};
ColorMatrix ColorMatrix=新的ColorMatrix(matrixItems);
ImageAttributes imageAtt=新的ImageAttributes();
imageAtt.SetColorMatrix(colorMatrix,ColorMatrixFlag.Default,ColorAdjustType.Bitmap);
使用(Graphics g=Graphics.FromImage(bmpOut))
g、 DrawImage(bmpIn、r、r.X、r.Y、r.宽度、r.高度、GraphicsUnit.像素、imageAtt);
返回bmpOut;
}
}
}
但我得到的结果是,图像显示的是alpha设置为100的图像的颜色。洋红色,而不是透明的。在test1.png和test2.png下保存的图像可以在那里进行检查:


如果你不在PictureBox控件上绘制位图,会发生什么事?@Neil如果我不绘制其中一幅图像(我注释行
pbx_1.image=bmp1;
),那么我什么也看不到(我看不到颜色。洋红色,就好像我设置了
bmp1=SetAlpha(bmp1,0)
,结果是一样的)。我认为问题在于您没有与“位图”交互。每个控件在“屏幕外”单独创建,然后在屏幕上单独合成。如果您将整个屏幕(或至少是要覆盖的内容的总平方)捕获到位图上,然后在其上绘制,然后将其复制回屏幕上,我认为您将看到您想要看到的内容。@Neil抱歉,我不确定您的意思。@Neil这可以工作,但如果可以移动表单,您将有很多闪烁。如果形状不能移动,它工作得非常好要移动带有半透明元素的透明窗口,您需要一些不同的东西。你可以试着吃两种形式的三明治。没有成功的保证。至少如果你希望在所有情况下都有好的结果双重缓冲和透明并不完全是朋友。