影象濾鏡藝術---保留細節的磨皮之C#程式實現
阿新 • • 發佈:2019-02-02
上一篇博文“保留細節的磨皮濾鏡之PS實現”一文中,我簡單介紹了本人自己總結的一種非常簡單的磨皮濾鏡,這個濾鏡在磨光面板的同時,會保留很不錯的細節,今天,我將介紹使用C#程式實現這個磨皮的過程。
這裡,我們同樣是使用ZPhotoEngine庫來實現,畢竟這個庫中實現的效果跟PS是幾乎一模一樣的,關於下載地址,文章最後會給出,廢話不多說了,磨皮步驟如下:
一,對原圖的副本a執行表面模糊,半徑15;
二,對原圖執行高反差保留,半徑1.0;
三,對高反差結果與原圖做線性光圖層處理,50%透明度即可;
根據以上三步,我的磨皮類主要程式碼如下:
介面部分主要程式碼如下:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Drawing.Imaging; namespace TestDemo { unsafe class ImageFilter { ZPhotoEngineDll zp = new ZPhotoEngineDll(); public Bitmap SoftSkinFilter(Bitmap src, int blurRadius) { //表面模糊圖層 Bitmap a = zp.SurfaceBlur(src, 28, blurRadius); //高反差圖層 Bitmap highPass = zp.HighPassProcess(src, 1.0f); BitmapData srcData = a.LockBits(new Rectangle(0, 0, a.Width, a.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); BitmapData dstData = highPass.LockBits(new Rectangle(0, 0, highPass.Width, highPass.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte* p = (byte*)srcData.Scan0; byte* dstP = (byte*)dstData.Scan0; int offset = srcData.Stride - a.Width * 4; int temp = 0; for (int j = 0; j < a.Height; j++) { for (int i = 0; i < a.Width; i++) { ////////////////Process image... //線性光圖層混合 temp = zp.ModeLinearLight(p[0], dstP[0]); //透明度50% dstP[0] = (byte)((p[0] + temp) >> 1); temp = zp.ModeLinearLight(p[1], dstP[1]); dstP[1] = (byte)((p[1] + temp) >> 1); temp = zp.ModeLinearLight(p[2], dstP[2]); dstP[2] = (byte)((p[2] + temp) >> 1); dstP += 4; p += 4; } dstP += offset; p += offset; } a.UnlockBits(srcData); highPass.UnlockBits(dstData); return highPass; } } }
程式介面如下:using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing.Imaging; namespace TestDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } #region 變數宣告 //影象路徑 private String curFileName = null; //當前影象變數 private Bitmap curBitmap = null; //原始影象變數 private Bitmap srcBitmap = null; // ImageFilter imfilter = new ImageFilter(); #endregion #region 影象開啟儲存模組 //開啟影象函式 public void OpenFile() { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "所有影象檔案 | *.bmp; *.pcx; *.png; *.jpg; *.gif;" + "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf|" + "點陣圖( *.bmp; *.jpg; *.png;...) | *.bmp; *.pcx; *.png; *.jpg; *.gif; *.tif; *.ico|" + "向量圖( *.wmf; *.eps; *.emf;...) | *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf"; ofd.ShowHelp = true; ofd.Title = "開啟影象檔案"; if (ofd.ShowDialog() == DialogResult.OK) { curFileName = ofd.FileName; try { curBitmap = (Bitmap)System.Drawing.Image.FromFile(curFileName); srcBitmap = new Bitmap(curBitmap); } catch (Exception exp) { MessageBox.Show(exp.Message); } } } //儲存影象函式 public void SaveFile() { SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "PNG檔案(*.png)|*.png"; if (sfd.ShowDialog() == DialogResult.OK) { pictureBox1.Image.Save(sfd.FileName, ImageFormat.Png); } } //開啟影象 private void openBtn_Click(object sender, EventArgs e) { OpenFile(); if (curBitmap != null) { pictureBox1.Image = (Image)curBitmap; } } //儲存影象 private void saveBtn_Click(object sender, EventArgs e) { if (pictureBox1.Image != null) SaveFile(); } #endregion //確定 private void okBtn_Click(object sender, EventArgs e) { if (pictureBox1.Image != null) { int radius = Convert.ToInt32(textBox1.Text.ToString()); if (radius >= 0 && radius <= 20) { pictureBox1.Image = (Image)imfilter.SoftSkinFilter(curBitmap, radius); } } } } }
最後,放上效果圖:
原圖 C#程式效果圖
PS效果圖
大家可以對比一下,PS效果跟本文實現效果是一模一樣的,差別幾乎是肉眼看不到的呵呵。
最後,放上一些下載連線:
1,ZPhotoEngine庫下載連線:點選開啟連結
2,磨皮程式碼DEMO免費下載連線:點選開啟連結