Reputation: 117
I try to display a cached Bitmap in Winforms (for performance reasons). I have a problem cause I cant draw it.
The exaple in this answer https://stackoverflow.com/a/6474581/1676819 says that there should be something like
graphics.DrawCachedBitmap(bitmap, 0, 0);
I cant find it.
What I've done so far:
CachedBitmap
CachedBitmap tempCBm = new CachedBitmap(new BitmapImage(new Uri(@"D:\test.bmp")),BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
I tried to draw it with the standard method (causes error)
private void CustomPaint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(tempCBm, 0,0);//error
}
Can somebody tell me what am I´m doing wrong? Many thanks in advance.
Upvotes: 3
Views: 2849
Reputation: 5525
CachedBitmap
is not available through .NET. It is a feature of GDI+. Use Bitmap
instead. If you need to optimize for performance, then you can use the unsafe
context in C# for faster bitmap access.
A nice tutorial is available here: http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp.
Upvotes: 3
Reputation: 22084
It is possible to use cached bitmap - but for some reason it is not available in standard C# api. You can circumvent around that however - make a managed C++ library that will encapsulate methods you want to expose to C#.
See my github repo - https://github.com/svejdo1/CachedBitmap
C++ utility class to expose cached bitmap
#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);
}
};
}
Example usage from WinForm application:
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);
}
}
Upvotes: 3