當前位置:編程學習大全網 - 源碼下載 - Net繪圖如何給圖片增加透明度

Net繪圖如何給圖片增加透明度

 首先我們強調壹下opacity的概念 是 不透明度 它表示的是兩個圖層之間的關系 即該屬性隸屬於本圖層 它表示與本圖層下面圖層之間的像素合成關系 當opacity= %時 表示本圖層完全不透明 因此下面的像素完全被遮擋 當opacity= 時 表示本圖層完全透明 即能看到下面的圖層 這是photoshop中最基本的壹個算法 表達如下

 像素結果=底部圖層*( opacity)+本圖層*opacity;

 當有多個圖層x x x 混合時 表達如下 (最底層的不透明度為 )

 x=(( k )x +k *x )( k )+k *x = ( k )( k )x + k ( k )x + k *x ;

 那麽繪制透明度水印的方法也就非常直觀了 因為類庫中的ImageAttributes屬性裏面並沒有提供像素合成的繪制選項 因此我們自己實現上面的算法 方法是 首先準備壹個小的水印圖片 我們先把原圖在水印下面的部分繪制上去 然後在吧水印的文本或圖片繪制上去 然後把原圖和水印圖片的內存數據鎖定(防止操作系統移動內存) 然後直接用上面的算法改寫原圖的位圖數據 解鎖內存即得到最終加了水印的圖片

 代碼如下 下面是繪制文本類型的水印 只需提供水印文本內容 繪制起始坐標即可 註意 為了簡單直觀起見 代碼中都沒有做參數驗證 例如水印是否超出原圖範圍 如果超出範圍將引發對超過內存邊界的訪問限制(引發異常) 下面使用了unsafe代碼 因此項目屬性 >Build中 應勾選允許不安全代碼 否則無法編譯 在下面代碼中的定位方式是非常熟悉的 再次強調的是以下的概念

 scan 指針 內存數據的起始地址 (換句話說 就是指向第壹個掃描行第壹個像素的Blue)

 bpp bit per pixel

 stride 掃描行寬度 =width*bpp/ 並在結尾補 ~ 個字節的 以湊齊到 字節整數倍

 之所以橫坐標乘以 是因為我們鎖定的方式是 bppRgb(最後壹個參數指定了數據的bpp) 這意味這每個像素占據了 個字節 因此i要乘以 來跳躍到下壹個像素 如果用 bppRGB鎖定 則每個像素在內存占據 字節 相應的i應該乘以

 Code 文本水印

 /// <summary>

 /// 給壹個位圖繪制水印文字(沒有驗證水印是否超出圖片邊界!)

 /// </summary>

 /// <param name= text >水印文本</param>

 /// <param name= x >起始點</param>

 /// <param name= y >起始點</param>

 /// <param name= opacity >不透明度 ~ </param>

 private Bitmap DrawWatermark(Image image string text Font font Brush brush int x int y double opacity)

 {

 Bitmap bm = new Bitmap(image);

 Graphics g =Graphics FromImage(bm );

 //測量水印文字的大小 然後申請壹個新的位圖

 SizeF sizef=g MeasureString(text font);

 Bitmap bm =new Bitmap((int)sizef Width (int)sizef Height);

 Graphics g =Graphics FromImage(bm );

 g DrawImage(bm new Rectangle(x y bm Width bm Height) GraphicsUnit Pixel);

 g DrawString(text font brush );

 BitmapData data =bm LockBits(new Rectangle( bm Width bm Height) ImageLockMode ReadWrite PixelFormat Format bppRgb);

 BitmapData data =bm LockBits(new Rectangle( bm Width bm Height) ImageLockMode ReadWrite PixelFormat Format bppRgb);

 unsafe

 {

 byte* p =(byte*)(void*)data Scan ;

 byte* p =(byte*)(void*)data Scan ;

 for(int j= ;j<bm Height;j++)

 {

 for(int i= ;i<bm Width* ;i++)

 {

 p [(y+j)*data Stride+i]=(byte)(p [(y+j)*data Stride+i]*( opacity)+opacity*p [j*data Stride+i]);

 }

 }

 bm UnlockBits(data );

 bm UnlockBits(data );

 }

 return bm ;

 }

 還有壹種情況是 我們事先做作好水印 它是壹個圖片 更多的人在photoshop中使用壹個自己設計好的logo 保存為壹個 畫筆形狀 制作時只要選中此畫筆壹蓋就好了 實際上這種類型的水印是壹個圖片 為了加這種類型的水印 引入下面的overload方法 指定水印圖片和透明色

 Code 圖片水印

 /// <param name= image >原圖</param>

 /// <param name= wmImg >水印圖片</param>

 /// <param name= key >透明色</param>

 /// <param name= x >起始點</param>

 /// <param name= y ></param>

 /// <param name= opacity >不透明度</param>

 /// <returns></returns>

 private Bitmap DrawWatermark(Image image Bitmap wmImg Color key int x int y double opacity)

 {

 Bitmap bm = new Bitmap(image); //克隆原圖 它也是我們的返回值

 Bitmap bm = new Bitmap(wmImg Width wmImg Height); //準備的水印圖片

 Graphics g = Graphics FromImage(bm );

 ImageAttributes att = new ImageAttributes();

 att SetColorKey(key key ColorAdjustType Bitmap); //設定透明色

 g DrawImage(bm new Rectangle(x y bm Width bm Height) GraphicsUnit Pixel);

 g DrawImage(wmImg new Rectangle( bm Width bm Height) bm Width bm Height GraphicsUnit Pixel att);

 g Dispose();

  這裏的代碼和上面的方法代碼相同 因此省略

 return bm ;

 }

 以上兩種效果的截圖

 ?( ) ( )

 ASP NET中如何使用unsafe選項

 實際需要在ASP NET中使用unsafe選項

 集體的方法是 找到工程的nfig文件 在configuration節中加入:

 <dedom>

 <pilers>

 <piler

 language= c#;cs;csharp extension= cs

 pilerOptions= /unsafe

 type= Microsoft CSharp CSharpCodeProvider System Version= Culture=neutral PublicKeyToken=b a c e />

 </pilers>

lishixinzhi/Article/program/net/201311/13652

  • 上一篇:Trace-based和Method-based的JIT編譯器有什麽區別?各自優勢在哪
  • 下一篇:幸運28源代碼出售
  • copyright 2024編程學習大全網