在 WinForms 中绘制缓存位图



我尝试在Winforms中显示缓存的位图(出于性能原因)。我有一个问题,因为我无法画它。这个答案中的 https://stackoverflow.com/a/6474581/1676819 说应该有类似的东西 graphics.DrawCachedBitmap(bitmap, 0, 0); 我找不到它。

到目前为止我做了什么:

  • 我添加了演示核心.dll作为参考
  • 我创建了一个CachedBitmap

CachedBitmap tempCBm = new CachedBitmap(new BitmapImage(new Uri(@"D:test.bmp")),BitmapCreateOptions.None, BitmapCacheOption.OnLoad);

  • 我尝试使用标准方法绘制它(导致错误)

    private void CustomPaint(object sender, PaintEventArgs e)
    {
            e.Graphics.DrawImage(tempCBm, 0,0);//error
    }
    

有人可以告诉我我做错了什么吗?提前非常感谢。

CachedBitmap无法

通过 .NET 使用。这是 GDI+ 的一项功能。请改用Bitmap。如果需要优化性能,则可以使用 C# 中的unsafe上下文来加快位图访问速度。

这里有一个很好的教程:http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp。

可以使用缓存位图,但由于某种原因,它在标准 C# API 中不可用。但是,您可以绕过这一点 - 创建一个托管C++库,该库将封装要向 C# 公开的方法。

查看我的 github 存储库 - https://github.com/svejdo1/CachedBitmap

C++实用程序类以公开缓存的位图

#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
using namespace Gdiplus;
namespace CachedBitmapUtility {
    public ref class BitmapUtility {
        public:
            static void* CreateCachedBitmapPtr(void* bitmapPtr, void* graphicsHdc) {
                Graphics graphics((HDC)graphicsHdc);
                CachedBitmap* result = new CachedBitmap((Bitmap*)bitmapPtr, &graphics);
                return result;
            }
            static void DisposeCachedBitmap(void* cachedBitmapPtr) {
                delete (CachedBitmap*)cachedBitmapPtr;
            }
            static void DisposeBitmap(void* bitmapPtr) {
                delete (Bitmap*)bitmapPtr;
            }
            static void* GetBitmapPtrFromHICON(void* hicon) {
                return (void*)Bitmap::FromHICON((HICON)hicon);
            }
            static void DrawCachedBitmap(void* hdc, void* cachedBitmapPtr, int x, int y) {
                Graphics graphics((HDC)hdc);
                graphics.DrawCachedBitmap((CachedBitmap*)cachedBitmapPtr, x, y);
            }
    };
}

WinForm 应用程序中的示例用法:

public partial class MainForm : Form {
  IntPtr m_BitmapPtr;
  IntPtr m_CachedBitmapPtr = IntPtr.Zero;
  public MainForm() {
    InitializeComponent();
    Bitmap bitmap;
    using (var stream = typeof(MainForm).Assembly.GetManifestResourceStream("FormApplication.character.png")) {
      bitmap = (Bitmap)Bitmap.FromStream(stream);
    }
    unsafe {
      m_BitmapPtr = (IntPtr)BitmapUtility.GetBitmapPtrFromHICON((void*)bitmap.GetHicon());
    }
  }
  protected override void OnClosed(EventArgs e) {
    // TODO: refactor - dispose should happen in Dispose event
    unsafe {
      BitmapUtility.DisposeBitmap((void*)m_BitmapPtr);
      BitmapUtility.DisposeCachedBitmap((void*)m_CachedBitmapPtr);
    }
  }
  protected override void OnPaint(PaintEventArgs e) {
    var graphics = e.Graphics;
    IntPtr hdc;
    if (m_CachedBitmapPtr == IntPtr.Zero) {
      hdc = graphics.GetHdc();
      unsafe {
        m_CachedBitmapPtr = (IntPtr)BitmapUtility.CreateCachedBitmapPtr((void*)m_BitmapPtr, (void*)hdc);
      }
      graphics.ReleaseHdc(hdc);
    }
    hdc = graphics.GetHdc();
    unsafe {
      BitmapUtility.DrawCachedBitmap((void*)hdc, (void*)m_CachedBitmapPtr, 0, 0);
    }
    graphics.ReleaseHdc(hdc);
  }
}

最新更新