將控件保存為圖片

原文:將控件保存為圖片

??????????????????????????????????????? 將控件保存為圖片

???????????????????????????????????????????????? 周銀輝

?

這里分別提供win form?和 wpf 兩種方式

對于.net 2.0 我們可以簡單地利用?BitBlt 函數來實現,非常簡單,代碼如下:

????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;
????????}

????}

?

其中 SRCCOPY?=?0xCC0020, 表示將源直接拷貝到目標。

?

對于WPF,無法獲得控件的hdc, 所以不能使用bitblt函數了,但幸運的是,其提供了一個RenderTargetBitmap的類型,可以將控件繪制到改類型的類型是示例上,比如:

?

var?renderBitmap?=?
?????????
new?RenderTargetBitmap(w,?h,?96d,96d,?PixelFormats.Pbgra32);

renderBitmap.Render(controlToConvert);

?

其可以直接作為Image控件的源以便顯示,如果要將其保存下來(保存到流中),則需要用到BitmapEncoder, 將上面的位圖添加到encoder的幀中,然后調用save方法便可。

包裝好的代碼如下:

?

ExpandedBlockStart.gif點擊展開
????internal?enum?ImageType
????{
????????Bmp,
????????Gif,
????????Jpeg,
????????Png,
????????Tiff,
????????Wdp
????}

????
internal?static?class?ControlToImageConverter
????{

????????
///?<summary>
????????
///?Convert?any?control?to?a?PngBitmapEncoder
????????
///?</summary>
????????
///?<param?name="controlToConvert">The?control?to?convert?to?an?ImageSource</param>
????????
///?<param?name="imageType">The?image?type?will?indicate?the?type?of?return?bitmap?encoder</param>
????????
///?<returns>The?returned?ImageSource?of?the?controlToConvert</returns>
????????private?static?BitmapEncoder?GetImageFromControl(FrameworkElement?controlToConvert,?ImageType?imageType)
????????{

????????????var?bounds?
=?controlToConvert.GetBounds(controlToConvert.Parent?as?Visual);

????????????var?renderBitmap?
=?new?RenderTargetBitmap((Int32)bounds.Width,?(Int32)bounds.Height,?96d,
??????????????????????????????????????????????????????96d,?PixelFormats.Pbgra32);
????????????renderBitmap.Render(controlToConvert);

????????????BitmapEncoder?encoder?
=?GetBitmapEncoderByImageType(imageType);

????????????
//?puch?rendered?bitmap?into?it
????????????encoder.Frames.Add(BitmapFrame.Create(renderBitmap));

????????????
return?encoder;
????????}

????????
private?static?Rect?GetBounds(this?FrameworkElement?element,?Visual?from)
????????{
????????????Rect?rect?
=?Rect.Empty;

????????????
try
????????????{
????????????????GeneralTransform?transform?
=?element.TransformToVisual(from);
????????????????rect?
=?transform.TransformBounds(new?Rect(0,?0,?element.ActualWidth,?element.ActualHeight));
????????????????
//?ReSharper?disable?EmptyGeneralCatchClause
????????????}
????????????
catch
????????????
//?ReSharper?restore?EmptyGeneralCatchClause
????????????{

????????????}

????????????
return?rect;
????????}

????????
///?<summary>
????????
///?Get?an?encoder?by?a?specify?image?type
????????
///?</summary>
????????
///?<param?name="type">the?image?type</param>
????????
///?<returns>return?an?eccoder</returns>
????????private?static?BitmapEncoder?GetBitmapEncoderByImageType(ImageType?type)
????????{
????????????
switch?(type)
????????????{
????????????????
case?ImageType.Bmp:
????????????????????
return?new?BmpBitmapEncoder();
????????????????
case?ImageType.Gif:
????????????????????
return?new?GifBitmapEncoder();
????????????????
case?ImageType.Jpeg:
????????????????????
return?new?JpegBitmapEncoder();
????????????????
case?ImageType.Png:
????????????????????
return?new?PngBitmapEncoder();
????????????????
case?ImageType.Tiff:
????????????????????
return?new?TiffBitmapEncoder();
????????????????
case?ImageType.Wdp:
????????????????????
return?new?WmpBitmapEncoder();
????????????????
default:
????????????????????
return?new?PngBitmapEncoder();
????????????}
????????}

????????
///?<summary>
????????
///?Get?the?iamge?type?by?image?file?name
????????
///?</summary>
????????
///?<param?name="fileName">the?file?name?of?an?image</param>
????????
///?<returns>the?iamge?type</returns>
????????private?static?ImageType?GetImageTypeByFileName(string?fileName)
????????{
????????????ImageType?returnType?
=?ImageType.Png;

????????????var?extension?
=?Path.GetExtension(fileName);
????????????
if?(!String.IsNullOrEmpty(extension))
????????????{
????????????????
switch?(extension.ToLower())
????????????????{
????????????????????
case?".bmp":
????????????????????????returnType?
=?ImageType.Bmp;
????????????????????????
break;
????????????????????
case?".gif":
????????????????????????returnType?
=?ImageType.Gif;
????????????????????????
break;
????????????????????
case?".jpeg":
????????????????????
case?".jpg":
????????????????????
case?".jpe":
????????????????????
case?"jfif":
????????????????????????returnType?
=?ImageType.Jpeg;
????????????????????????
break;
????????????????????
case?".png":
????????????????????????returnType?
=?ImageType.Png;
????????????????????????
break;
????????????????????
case?".tiff":
????????????????????
case?".tif":
????????????????????????returnType?
=?ImageType.Tiff;
????????????????????????
break;
????????????????????
case?".wdp":
????????????????????????returnType?
=?ImageType.Wdp;
????????????????????????
break;
????????????????????
default:
????????????????????????returnType?
=?ImageType.Png;
????????????????????????
break;
????????????????}
????????????}

????????????
return?returnType;
????????}

????????
///?<summary>
????????
///?Get?an?ImageSource?of?a?control
????????
///?</summary>
????????
///?<param?name="controlToConvert">The?control?to?convert?to?an?ImageSource</param>
????????
///?<param?name="imageType">the?image?type</param>
????????
///?<returns>The?returned?ImageSource?of?the?controlToConvert</returns>
????????public?static?BitmapSource?GetImageOfControl(FrameworkElement?controlToConvert,?ImageType?imageType)
????????{
????????????
//?return?first?frame?of?image?
????????????var?encoder?=?GetImageFromControl(controlToConvert,?imageType);
????????????
if?(encoder?!=?null?&&?encoder.Frames?!=?null?&&?encoder.Frames.Count?>?0)
????????????{
????????????????
return?encoder.Frames[0];
????????????}

????????????
return?new?BitmapImage();
????????}

????????
///?<summary>
????????
///?Get?an?ImageSource?of?a?control(Jpeg?as?default?type)
????????
///?</summary>
????????
///?<param?name="controlToConvert">The?control?to?convert?to?an?ImageSource</param>
????????
///?<returns>The?returned?ImageSource?of?the?controlToConvert</returns>
????????public?static?BitmapSource?GetImageOfControl(FrameworkElement?controlToConvert)
????????{
????????????
return?GetImageOfControl(controlToConvert,?ImageType.Jpeg);
????????}

????????
///?<summary>
????????
///?Save?an?image?of?a?control
????????
///?</summary>
????????
///?<param?name="controlToConvert">The?control?to?convert?to?an?ImageSource</param>
????????
///?<param?name="fileName">The?location?to?save?the?image?to</param>
????????
///?<returns>The?returned?ImageSource?of?the?controlToConvert</returns>
????????public?static?Boolean?SaveImageOfControl(FrameworkElement?controlToConvert,?String?fileName)
????????{
????????????
try
????????????{
????????????????var?imageType?
=?GetImageTypeByFileName(fileName);

????????????????
using?(var?outStream?=?new?FileStream(fileName,?FileMode.Create))
????????????????{
????????????????????var?encoder?
=?GetImageFromControl(controlToConvert,?imageType);
????????????????????encoder.Save(outStream);
????????????????}
????????????}
????????????
catch?(Exception?e)
????????????{
#if?DEBUG
????????????????Console.WriteLine(
"Exception?caught?saving?stream:?{0}",?e.Message);
#endif
????????????????
return?false;
????????????}

????????????
return?true;
????????}

????}

?

?

注意到上面的GetImageOfControl方法返回的實際是BitmapFrame, 其是BitmapSource的一種,如果你更習慣使用BitmapImage的話,免費贈送如下方法:

????????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();

????????????
return?bmp;
????????}

?

?

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/277687.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/277687.shtml
英文地址,請注明出處:http://en.pswp.cn/news/277687.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux基礎命令---get獲取ftp文件

get 使用lftp登錄ftp服務器之后&#xff0c;可以使用get指令從服務器獲取文件。 1、語法 get [-E] [-a] [-c] [-O base] rfile [-o lfile] 2、選項列表 選項 說明 -o 指定輸出文件的名字&#xff0c;不指定則使用原來的名字 -c 如果失敗&#xff0c;持續獲取 -E 獲取…

Unity3D學習筆記之二資源導入以及工程管理

本次教程&#xff0c;我們來建立自己的一個工程并導入模型&#xff0c;對模型進行處理。特別說明&#xff1a;這系列教程參考自人人素材翻譯組出品的翻譯教程《Unity游戲引擎的基礎入門視頻教程》&#xff0c;本博客中采用的模型和方法均來源于此。這是我瀏覽過好多教程后覺得講…

關于cocos creator換裝功能的實踐與思考

2019獨角獸企業重金招聘Python工程師標準>>> 最近在做一個基于cocos creator的微信小游戲&#xff0c;其中一個主要的功能是給角色進行換裝。先來說下開發環境&#xff1a; cocos creator1.9.3spine 在官方的文檔中只有設置皮膚的接口&#xff0c;實際上是存在可以部…

pl/sql查詢表數據,報錯ORA-03115:不支持的網絡數據類型或表示法

今天測試人員遇到一個問題&#xff1a;pl/sql查詢表數據&#xff0c;報錯ORA-03115&#xff1a;不支持的網絡數據類型或表示法 我在plsql上查詢這張表是沒有問題的&#xff0c;去看了那張表&#xff0c;發現有個字段類型是binary_double&#xff0c; 查資料發現這是oracle10才出…

抖店一件代發實操,干貨滿滿!

我是電商珠珠 沒有貨源的新手&#xff0c;在店鋪剛開始的時候可以搞無貨源模式&#xff0c;也就是一件代發&#xff0c;去搬運別人店鋪的商品到自己店鋪&#xff0c;再去利用信息差去賺取差價。 很多人不知道具體要怎么做&#xff0c;今天我就來給大家講一講。 一、入駐 入…

Unity3D學習筆記之三Prefab組件的使用

本次教程&#xff0c;我們來創建一個簡單的Prefab組件。教程參考自人人素材翻譯組出品的翻譯教程《Unity游戲引擎的基礎入門視頻教程》。說到Prefab&#xff0c;中文翻譯為預設體&#xff0c;在Unity官方的書本《Unity4.X從入門到精通》中的解釋是&#xff1a;可以理解為是一個…

JavaScript之閉包

不少開發人員總是搞不清匿名函數和閉包這兩個概念&#xff0c;因此經常混用。閉包是指有權訪問另一個函數作用域中的變量的函數。創建閉包的常見方式&#xff0c;就是在一個函數內部創建另一個函數 --《JavaScript高級程序設計》 轉載于:https://www.cnblogs.com/songsongblue/…

【躍遷之路】【522天】程序員高效學習方法論探索系列(實驗階段279-2018.07.12)...

(躍遷之路)專欄 【躍遷之路】獎勵金計劃正式開始 從2018.7.1起&#xff0c;【躍遷之路】獎勵金計劃正式起航&#xff0c;從今以后&#xff0c;每月1日&#xff0c;我會將自己個人上月收入的1%計入【躍遷之路】獎勵金池&#xff0c;積累到足夠金額后&#xff0c;將適時用于獎勵那…

迷茫在路口——致我的2014

今天是2015年一月一日&#xff0c;2014年已經過去了。這意味著再過六個月整&#xff0c;我就要大學畢業&#xff0c;開始為自己的未來拼搏。這一年&#xff0c;我過的充實且迷茫。說2014充實&#xff0c;是因為我從寒假結束到有一個寒假的到來&#xff0c;幾乎沒有怎么閑下來&a…

Codeforces 173E Camping Groups 線段樹

Camping Groups 我們先計算出&#xff0c; 每個點當leader所能掌控的最多人數。 然后我們把詢問離線&#xff0c; 丟到responsibility最大的那個地方去。 然后從大到小往線段樹里加人&#xff0c; 加入完之后處理掉當前的詢問。 如果強制在線的話就只能樹套樹啦。 #include<…

tomcat閃退解決方案

在這幾天&#xff0c;遇到一個Tomcat啟動閃退的問題&#xff0c;通過查閱各種資料&#xff0c;算是完美解決。在此分享給朋友們。 首先&#xff0c;確定你的問題在哪里 1.查詢錯誤&#xff1a;winR 輸入cmd&#xff0c;進入一般處理程序。通過cd 找到你Tomcat的bin文件夾&#…

《古劍奇譚2》詳細測評心得

期待已久的《古劍奇譚2》。仔仔細細的玩下來給我的感覺還是不錯的。燭龍也不愧是國產單機的良心公司了&#xff0c;回合制的戰斗方式改成了即時戰斗類。 的確&#xff0c;國產動作類的游戲經驗目前等于零。《古劍2》一改以往國產網游的作風跳出了回合制的圈子實屬不易&#xff…

LeetCode 581. 最短無序連續子數組(Shortest Unsorted Continuous Subarray)

581. 最短無序連續子數組581. Shortest Unsorted Continuous Subarray 題目描述 給定一個整型數組&#xff0c;你需要尋找一個連續的子數組&#xff0c;如果對這個子數組進行升序排序&#xff0c;那么整個數組都會變為升序排序。 你找到的子數組應是最短的&#xff0c;請輸出它…

NFS4文件鎖機制探秘

2019獨角獸企業重金招聘Python工程師標準>>> 簡介 NFS4實現“租賃鎖”。每個鎖擁有一樣的“租賃期”。客戶端的讀寫操作將刷新“租賃期”。租賃期到期后&#xff0c;鎖將被服務器釋放。NFS4通過下述“模型”實現對鎖的管理&#xff1a; 1) 清晰地劃分客戶端和服務器…

Stay Hungry Stay Foolish——網絡學習平臺分享

從1月24號回家也有一陣子了&#xff0c;今天已經是31號&#xff0c;這一個周的中心思想就是一個字&#xff0c;玩。 學生一但遠離學校&#xff0c;就會碰到許多學習的阻力&#xff0c;有來自外界的&#xff0c;家里有活要干&#xff0c;有親戚要訪&#xff0c;有同學邀約&…

linux_check

linux_check echo "********CPU****************" echo 總核數 物理CPU個數 X 每顆物理CPU的核數 echo " 總邏輯CPU數 物理CPU個數 X 每顆物理CPU的核數 X 超線程數"echo 查看物理CPU個數 cat /proc/cpuinfo| grep "physical id"| sort| un…

Unity3D學習筆記之四完善Prefab并添加First Person Controller

好久沒學東西并用博客記錄了&#xff0c;這個年過的很懶散&#xff0c;慢慢臨近開學了&#xff0c;也要提前適應一下&#xff0c;寫寫東西&#xff0c;這樣開學才能更好的進入狀態呀&#xff5e;&#xff5e;本次筆記中&#xff0c;我們將來雕琢一個更加完善的Prefab&#xff0…

高精度(壓位+判負數+加減乘+讀寫)

本算法目前屬于還處于測試狀態&#xff0c;歡迎Hack&#xff01; struct gj{bool fu; //是否是負數int tt,mod; //高精的長度int s[40005]; //壓位用的數組inline gj(){ //整體初始化fu0; tt0; mod1e9;memset(s,0,sizeof(s));}inline gj read(){ register char ch; //高精度讀…

Hadoop從安裝Linux到搭建集群環境

簡介與環境準備  hadoop的核心是分布式文件系統HDFS以及批處理計算MapReduce。近年&#xff0c;隨著大數據、云計算、物聯網的興起&#xff0c;也極大的吸引了我的興趣&#xff0c;看了網上很多文章&#xff0c;感覺還是云里霧里&#xff0c;很多不必要的配置都在入門教程出現…

git推送本地分支到遠程分支

場景 有時候我們開發需要開一個分支,這樣可以有效的并行開發. 開分支有兩種方式: 一種是在遠程開好分支,本地直接拉下來;一種是本地開好分支,推送到遠程.遠程先開好分支然后拉到本地 git checkout -b feature-branch origin/feature-branch //檢出遠程的feature-branch分支到…