用位图变化模拟动画
本文关键字:动画 模拟 变化 位图 | 更新日期: 2023-09-27 18:13:42
我有一个键盘布局的位图,我将其"图像映射"到各个部分,因此我可以通过将其映射到整个位图来确定哪个"键"被点击了。
一旦确定了"键",我想缩小键占用的区域(通过几个像素),并在位图上绘制缩小尺寸的图像以模拟keydown
动作。密钥释放后,应恢复原始图像区域。
我需要在c#中为。NET 4.0做到这一点,谁能给我一些指示?
这是我到目前为止的代码:
//--- Private helper class.
private class ImageMap
{
public ImageMap(System.Drawing.Rectangle areaTeclaNormal, System.Windows.Forms.Keys key, string textString, System.Drawing.Rectangle areaTeclaPulsada)
{
AreaTeclaNormal = areaTeclaNormal;
Key = key;
TextString = textString;
BitmapTeclaNormal = getBitmapFrom(MapaTecladoNormal, areaTeclaNormal);
BitmapTeclaPulsada = getBitmapFrom(MapaTecladoPulsado, areaTeclaPulsada);
}
public System.Drawing.Rectangle AreaTeclaNormal { get; private set; }
public System.Windows.Forms.Keys Key { get; private set; }
public string TextString { get; private set; }
public System.Drawing.Bitmap BitmapTeclaNormal { get; private set; }
public System.Drawing.Bitmap BitmapTeclaPulsada { get; private set; }
public bool? IsTeclaPulsada { get; set; }
public static System.Drawing.Bitmap MapaTecladoNormal { get; set; }
public static System.Drawing.Bitmap MapaTecladoPulsado { get; set; }
private static System.Drawing.Bitmap getBitmapFrom(System.Drawing.Bitmap bmTecladoPulsado, System.Drawing.Rectangle rectangle)
{
return bmTecladoPulsado.Clone(rectangle, bmTecladoPulsado.PixelFormat);
}
}
//--- This is a class member to store the list of maps.
private readonly List<ImageMap> listaImageMaps = new List<ImageMap>();
//--- Inside my c'tor.
listaImageMaps.Add(new ImageMap(new System.Drawing.Rectangle(3, 187, 60, 60), System.Windows.Forms.Keys.NumPad1, "1", new System.Drawing.Rectangle(3, 174, 56, 56)));
listaImageMaps.Add(new ImageMap(new System.Drawing.Rectangle(64, 187, 60, 60), System.Windows.Forms.Keys.NumPad2, "2", new System.Drawing.Rectangle(60, 174, 56, 56)));
listaImageMaps.Add(new ImageMap(new System.Drawing.Rectangle(124, 187, 60, 60), System.Windows.Forms.Keys.NumPad3, "3", new System.Drawing.Rectangle(116, 174, 56, 56)));
//--- Eventa handlers
private void editImage_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
ImageMap imageMap = listaImageMaps.Find(item => item.AreaTeclaNormal.IntersectsWith(new System.Drawing.Rectangle(e.X, e.Y, 1, 1)));
if(imageMap != null)
{
imageMap.IsTeclaPulsada = true;
editImage.Update();
}
}
private void editImage_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
ImageMap imageMap = listaImageMaps.Find(item => item.IsTeclaPulsada.HasValue && item.IsTeclaPulsada == true);
if(imageMap != null)
{
imageMap.IsTeclaPulsada = false;
editImage.Update();
}
}
private void editImage_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
ImageMap imageMap = listaImageMaps.Find(item => item.IsTeclaPulsada.HasValue);
if(imageMap != null)
{
if(imageMap.IsTeclaPulsada == true)
{
e.Graphics.DrawImage(imageMap.BitmapTeclaPulsada, imageMap.AreaTeclaNormal.Left + 2, imageMap.AreaTeclaNormal.Top + 2, imageMap.BitmapTeclaPulsada.Width, imageMap.BitmapTeclaPulsada.Height);
}
else
{
e.Graphics.DrawImage(imageMap.BitmapTeclaNormal, imageMap.AreaTeclaNormal.Left, imageMap.AreaTeclaNormal.Top, imageMap.BitmapTeclaNormal.Width, imageMap.BitmapTeclaNormal.Height);
imageMap.IsTeclaPulsada = null;
}
}
}
ImageMap助手类用于定义主位图中的不同区域,它定义了被占用的区域、未按下的键图像和按下的键图像。
我使用可空的IsTeclaPulsada属性来指示是否需要任何绘制:True =绘制按下的键图像,False =绘制正常的键图像,Null =不需要处理。
我使用MouseDown和MouseUp事件来触发进程,并使用Paint事件来绘制所需的键状态区域。
第一个事件(MouseDown)绘制按下的图像,但是当MouseUp触发绘制事件时,不会立即绘制未按下的图像(这需要几秒钟!)
好的,解决方案似乎是使用editImage.Refresh()代替editImage.Update()。