c#使用图形时闪烁.使用透明绘制图像
本文关键字:绘制 图像 透明 图形 闪烁 | 更新日期: 2023-09-27 18:01:40
我在使用graphics.Drawimage
绘制特定动画GIF图像时遇到闪烁问题。我用我的程序中的代码片段编写了一个小程序,以准确地显示我想要完成的任务,这是在桌面上直接显示透明的动画图像,并可以接受事件处理程序,如鼠标单击。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
namespace Transparancy_Example
{
class TransparentForm : System.Windows.Forms.Form
{
public TransparentForm()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
UpdateStyles();
this.TopMost = true;
this.FormBorderStyle = FormBorderStyle.None;
this.ShowInTaskbar = false;
this.AllowTransparency = true;
this.StartPosition = FormStartPosition.CenterScreen;
TransparentControl tc = new TransparentControl();
tc.Parent = this;
tc.Dock = DockStyle.Fill;
tc.BackColor = Color.Transparent;
tc.Image = Properties.Resources.animated_gif;
this.Controls.Add(tc);
this.Size = tc.Image.Size;
this.SetBounds(0, 0, Width, Height);
Bitmap bmp = new Bitmap(tc.Image);
Color makeColorTransparent = bmp.GetPixel(0, 0);
if (bmp.PixelFormat != PixelFormat.Format32bppArgb && makeColorTransparent.A != Color.Transparent.A)
{
this.TransparencyKey = bmp.GetPixel(0, 0);
}
else if (makeColorTransparent.A != Color.Transparent.A)
{
this.TransparencyKey = bmp.GetPixel(0, 0);
}
else
{
this.TransparencyKey = this.BackColor;
}
}
}
public class TransparentControl : Control
{
private readonly Timer refresher;
private Image _image;
public TransparentControl()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
UpdateStyles();
BackColor = Color.Transparent;
refresher = new Timer();
refresher.Tick += TimerOnTick;
refresher.Interval = 50;
refresher.Enabled = true;
refresher.Start();
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x020;
return cp;
}
}
protected override void OnMove(EventArgs e)
{
RecreateHandle();
}
protected override void OnPaint(PaintEventArgs e)
{
if (_image != null)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
double ratioX = (double)Width / (double)_image.Width;
double ratioY = (double)Height / (double)_image.Height;
double ratio = ratioX < ratioY ? ratioX : ratioY;
int newHeight = Convert.ToInt32((double)_image.Height * ratio);
int newWidth = Convert.ToInt32((double)_image.Width * ratio);
int posX = Convert.ToInt32((Width - ((double)_image.Width * ratio)) / 2);
int posY = Convert.ToInt32((Height - ((double)_image.Height * ratio)) / 2);
e.Graphics.DrawImage(_image, posX, posY, newWidth, newHeight);
ImageAnimator.UpdateFrames(_image);
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//Do not paint background
}
public void Redraw()
{
RecreateHandle();
}
private void TimerOnTick(object source, EventArgs e)
{
RecreateHandle();
refresher.Stop();
ImageAnimator.Animate(_image, onFrameChangedHandler);
}
private void onFrameChangedHandler(object sender, EventArgs e)
{
if (Parent != null)
{
this.Parent.Invalidate(this.Bounds, false);
}
}
public Image Image
{
get
{
return _image;
}
set
{
_image = value;
RecreateHandle();
}
}
}
}
一切看起来都很好,但是如果我尝试添加任何doublebuffering,就会出现很多问题。
我终于找到了自己问题的答案。
我将this.DoubleBuffered = true;
添加到TransparentForm中,并添加了如下的公共覆盖:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
不要问我为什么0x020
或0x0200
不工作,但覆盖CreateParams与CreateParams与TransparentControl双缓冲区相结合,不让图像闪烁并保持所有透明度。