将控件儲存為圖檔
周銀輝
這裡分别提供win form 和 wpf 兩種方式
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuQWZzUTOhljM0cTO2ATOwATNxMWM1EWYxEjY5ADNlFTNfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.gif)
public static class ControlToImageConverter
{
private const Int32 SRCCOPY = 0xCC0020;
[DllImport("gdi32.dll")]
internal static extern bool BitBlt(
IntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
Int32 dwRop // raster operation code
);
public static Bitmap GetImageOfControl(Control control)
{
var w = control.Size.Width;
var h = control.Size.Height;
Graphics gOfCtrl = control.CreateGraphics();
var bmp = new Bitmap(w, h, gOfCtrl);
Graphics gOfBmp = Graphics.FromImage(bmp);
IntPtr dc1 = gOfCtrl.GetHdc();
IntPtr dc2 = gOfBmp.GetHdc();
BitBlt(dc2, 0, 0, w, h, dc1, 0, 0, SRCCOPY);
gOfCtrl.ReleaseHdc(dc1);
gOfBmp.ReleaseHdc(dc2);
gOfCtrl.Dispose();
gOfBmp.Dispose();
return bmp;
}
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuQWZzUTOhljM0cTO2ATOwATNxMWM1EWYxEjY5ADNlFTNfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.gif)
其中 SRCCOPY = 0xCC0020, 表示将源直接拷貝到目标。
對于WPF,無法獲得控件的hdc, 是以不能使用bitblt函數了,但幸運的是,其提供了一個RenderTargetBitmap的類型,可以将控件繪制到改類型的類型是示例上,比如:
var renderBitmap =
new RenderTargetBitmap(w, h, 96d,96d, PixelFormats.Pbgra32);
renderBitmap.Render(controlToConvert);
其可以直接作為Image控件的源以便顯示,如果要将其儲存下來(儲存到流中),則需要用到BitmapEncoder, 将上面的位圖添加到encoder的幀中,然後調用save方法便可。
包裝好的代碼如下:
點選展開
注意到上面的GetImageOfControl方法傳回的實際是BitmapFrame, 其是BitmapSource的一種,如果你更習慣使用BitmapImage的話,免費贈送如下方法:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuQWZzUTOhljM0cTO2ATOwATNxMWM1EWYxEjY5ADNlFTNfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.gif)
public static BitmapImage ToBitmapImage(this BitmapSource bitmapSource)
var encoder = new JpegBitmapEncoder();
var memoryStream = new MemoryStream();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
encoder.Save(memoryStream);
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = new MemoryStream(memoryStream.ToArray());
bmp.EndInit();
memoryStream.Flush();
memoryStream.Close();
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuQWZzUTOhljM0cTO2ATOwATNxMWM1EWYxEjY5ADNlFTNfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.gif)