[英]How to Render a Transparent Cursor to Bitmap preserving alpha channel?
我使用下面的代碼渲染透明圖標:
private void button1_Click(object sender, EventArgs e)
{
// using LoadCursorFromFile from user32.dll
var cursor = NativeMethods.LoadCustomCursor(@"d:\Temp\Cursors\Cursors\aero_busy.ani");
// cursor -> bitmap
Bitmap bitmap = new Bitmap(48, 48, PixelFormat.Format32bppArgb);
Graphics gBitmap = Graphics.FromImage(bitmap);
cursor.DrawStretched(gBitmap, new Rectangle(0, 0, 32, 32));
// 1. Draw bitmap on a form canvas
Graphics gForm = Graphics.FromHwnd(this.Handle);
gForm.DrawImage(bitmap, 50, 50);
// 2. Draw cursor directly to a form canvas
cursor.Draw(gForm, new Rectangle(100, 50, 32, 32));
cursor.Dispose();
}
不幸的是我無法將透明光標渲染到位圖! 當我將Cursor直接繪制到窗體畫布時,它可以工作,但是當我將Cursor繪制到位圖時會出現問題。 任何建議都非常感謝。
您現在擁有的解決方案並不完全適用於托管代碼。 你自己的評論說你是來自user32.dll的P / Invoking LoadCursorFromFile
。 無論如何,使用Win32 API實際上並不是你應該害怕的。
正如我在評論中提到的,您嘗試做的事情通常是使用GDI +繪圖函數存在問題,就像.NET Framework提供的大多數函數一樣。 使用GDI可以更輕松地完成任務。 您可以使用以下代碼從光標(或圖標,它們基本上可以互換)創建一個尊重Alpha通道的位圖:
[StructLayout(LayoutKind.Sequential)]
private struct ICONINFO
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[DllImport("user32")]
private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO pIconInfo);
[DllImport("user32.dll")]
private static extern IntPtr LoadCursorFromFile(string lpFileName);
[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);
private Bitmap BitmapFromCursor(Cursor cur)
{
ICONINFO ii;
GetIconInfo(cur.Handle, out ii);
Bitmap bmp = Bitmap.FromHbitmap(ii.hbmColor);
DeleteObject(ii.hbmColor);
DeleteObject(ii.hbmMask);
BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
Bitmap dstBitmap = new Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat.Format32bppArgb, bmData.Scan0);
bmp.UnlockBits(bmData);
return new Bitmap(dstBitmap);
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
//Using LoadCursorFromFile from user32.dll, get a handle to the icon
IntPtr hCursor = LoadCursorFromFile("C:\\Windows\\Cursors\\Windows Aero\\aero_busy.ani");
//Create a Cursor object from that handle
Cursor cursor = new Cursor(hCursor);
//Convert that cursor into a bitmap
using (Bitmap cursorBitmap = BitmapFromCursor(cursor))
{
//Draw that cursor bitmap directly to the form canvas
e.Graphics.DrawImage(cursorBitmap, 50, 50);
}
}
如果此代碼無法編譯,請確保已為System.Drawing
, System.Drawing.Imaging
和System.Runtime.InteropServices
添加了using
語句。 還記得將Form1_Paint
方法連接為表單的Paint
事件的處理程序。
它經過測試可以工作:
@Cody Gray,對於色彩位低的游標不起作用。
另一種方法是使用Icon.ExtractAssociatedIcon
:
System.Drawing.Icon i = System.Drawing.Icon.ExtractAssociatedIcon(@"C:\Windows\Cursors\arrow_rl.cur");
System.Drawing.Bitmap b = i.ToBitmap();
希望有人幫助......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.