用位图变化模拟动画

本文关键字:动画 模拟 变化 位图 | 更新日期: 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()。