实例介绍
【实例简介】
【实例截图】
【核心代码】
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Runtime.InteropServices; using System.Drawing.Imaging; namespace PsFilters { /// <summary> /// Form1 的摘要说明。 /// </summary> public class Form1 : System.Windows.Forms.Form { //是否伸展置换图 private bool b_Stretch=false; //是否重复边缘象素 private bool b_Repeat=true; //水平比例 private int m_X=100; //垂直比例 private int m_Y=100; //原图 private Bitmap m_Bitmap; /// <summary> /// 设计器生成代码 /// </summary> private System.Windows.Forms.MainMenu mainMenu1; private System.Windows.Forms.MenuItem menuFile; private System.Windows.Forms.MenuItem menuFilter; private System.Windows.Forms.MenuItem menuDisplace; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.StatusBar statusBar1; private System.Windows.Forms.MenuItem menuOpen; private System.Windows.Forms.MenuItem menuInvert; private System.Windows.Forms.MenuItem menuSave; private System.Windows.Forms.MenuItem menuSaveAs; private System.Windows.Forms.MenuItem menuItem1; private System.Windows.Forms.MenuItem menuCreateZoomBM; private System.Windows.Forms.MenuItem menuItem2; private System.Windows.Forms.MenuItem menuAdjustLevel; private System.Windows.Forms.MenuItem mnCreateWaveBm; private MenuItem mnDrawWatermark; private MenuItem mnWatermark2; private IContainer components; public Form1() { // // Windows 窗体设计器支持所必需的 // InitializeComponent(); // // TODO: 在 InitializeComponent 调用后添加任何构造函数代码 // this.m_X=100; this.m_Y=100; this.menuFilter.Popup =new EventHandler(menuFilter_Popup); } /// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components); this.menuFile = new System.Windows.Forms.MenuItem(); this.menuOpen = new System.Windows.Forms.MenuItem(); this.menuSave = new System.Windows.Forms.MenuItem(); this.menuSaveAs = new System.Windows.Forms.MenuItem(); this.menuFilter = new System.Windows.Forms.MenuItem(); this.menuDisplace = new System.Windows.Forms.MenuItem(); this.menuInvert = new System.Windows.Forms.MenuItem(); this.menuItem1 = new System.Windows.Forms.MenuItem(); this.menuCreateZoomBM = new System.Windows.Forms.MenuItem(); this.mnCreateWaveBm = new System.Windows.Forms.MenuItem(); this.menuItem2 = new System.Windows.Forms.MenuItem(); this.menuAdjustLevel = new System.Windows.Forms.MenuItem(); this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.statusBar1 = new System.Windows.Forms.StatusBar(); this.mnDrawWatermark = new System.Windows.Forms.MenuItem(); this.mnWatermark2 = new System.Windows.Forms.MenuItem(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.SuspendLayout(); // // mainMenu1 // this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.menuFile, this.menuFilter, this.menuItem1, this.menuItem2}); // // menuFile // this.menuFile.Index = 0; this.menuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.menuOpen, this.menuSave, this.menuSaveAs}); this.menuFile.Text = "文件(&F)"; this.menuFile.Popup = new System.EventHandler(this.menuFile_Popup); // // menuOpen // this.menuOpen.Index = 0; this.menuOpen.Text = "打开(&O) Ctrl O"; this.menuOpen.Click = new System.EventHandler(this.menuOpen_Click); // // menuSave // this.menuSave.Index = 1; this.menuSave.Text = "存储(&S) Ctrl S"; // // menuSaveAs // this.menuSaveAs.Index = 2; this.menuSaveAs.Text = "存储为(&V) Ctrl Shift S"; this.menuSaveAs.Click = new System.EventHandler(this.menuSaveAs_Click); // // menuFilter // this.menuFilter.Index = 1; this.menuFilter.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.menuDisplace, this.menuInvert, this.mnDrawWatermark, this.mnWatermark2}); this.menuFilter.Text = "滤镜(&T)"; // // menuDisplace // this.menuDisplace.Index = 0; this.menuDisplace.Text = "置换"; this.menuDisplace.Click = new System.EventHandler(this.menuDisplace_Click); // // menuInvert // this.menuInvert.Index = 1; this.menuInvert.Text = "反相"; this.menuInvert.Click = new System.EventHandler(this.menuInvert_Click); // // menuItem1 // this.menuItem1.Index = 2; this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.menuCreateZoomBM, this.mnCreateWaveBm}); this.menuItem1.Text = "生成"; // // menuCreateZoomBM // this.menuCreateZoomBM.Index = 0; this.menuCreateZoomBM.Text = "无痕迹缩放置换图"; this.menuCreateZoomBM.Click = new System.EventHandler(this.menuCreateZoomBM_Click); // // mnCreateWaveBm // this.mnCreateWaveBm.Index = 1; this.mnCreateWaveBm.Text = "水波特效置换图"; this.mnCreateWaveBm.Click = new System.EventHandler(this.mnCreateWaveBm_Click); // // menuItem2 // this.menuItem2.Index = 3; this.menuItem2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.menuAdjustLevel}); this.menuItem2.Text = "图像"; // // menuAdjustLevel // this.menuAdjustLevel.Index = 0; this.menuAdjustLevel.Text = "调整色阶"; this.menuAdjustLevel.Click = new System.EventHandler(this.menuAdjustLevel_Click); // // pictureBox1 // this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; this.pictureBox1.Location = new System.Drawing.Point(0, 0); this.pictureBox1.Name = "pictureBox1"; this.pictureBox1.Size = new System.Drawing.Size(560, 413); this.pictureBox1.TabIndex = 0; this.pictureBox1.TabStop = false; // // statusBar1 // this.statusBar1.Location = new System.Drawing.Point(0, 391); this.statusBar1.Name = "statusBar1"; this.statusBar1.Size = new System.Drawing.Size(560, 22); this.statusBar1.TabIndex = 1; this.statusBar1.Text = "statusBar1"; // // mnDrawWatermark // this.mnDrawWatermark.Index = 2; this.mnDrawWatermark.Text = "绘制水印(文本)"; this.mnDrawWatermark.Click = new System.EventHandler(this.mnDrawWatermark_Click); // // mnWatermark2 // this.mnWatermark2.Index = 3; this.mnWatermark2.Text = "绘制水印(图片)"; this.mnWatermark2.Click = new System.EventHandler(this.mnWatermark2_Click); // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(560, 413); this.Controls.Add(this.statusBar1); this.Controls.Add(this.pictureBox1); this.Menu = this.mainMenu1; this.Name = "Form1"; this.Text = "Form1"; ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.ResumeLayout(false); } #endregion /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } /// <summary> /// 置换滤镜 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void menuDisplace_Click(object sender, System.EventArgs e) { //置换滤镜选项对话框 DisplaceDlg dlg1=new DisplaceDlg(); dlg1.Stretch=this.b_Stretch; // dlg1.Repeat=this.b_Repeat; dlg1.Multiplier_H=this.m_X; dlg1.Multiplier_V=this.m_Y; if(dlg1.ShowDialog()==DialogResult.OK) { this.b_Repeat=dlg1.Repeat; this.b_Stretch=dlg1.Stretch; this.m_X=dlg1.Multiplier_H; this.m_Y=dlg1.Multiplier_V; } else return; //打开一个置换图 Bitmap bm2; OpenFileDialog dlg2=new OpenFileDialog(); dlg2.Title="打开一个置换图"; dlg2.Filter="BMP(*.BMP)|*.bmp|JEPG(*.JPG;*.JEPG)|*.jpg;*.jepg"; if(dlg2.ShowDialog()==DialogResult.OK) { try { bm2=new Bitmap(dlg2.FileName); } catch(Exception e002) { MessageBox.Show("打开图片失败!\n" e002.Message); return; } } else return; //开始置换 this.pictureBox1.Image=this.DispaceUnsafe((Bitmap)(this.pictureBox1.Image),bm2); this.pictureBox1.Invalidate(); } private void menuOpen_Click(object sender, System.EventArgs e) { OpenFileDialog dlg=new OpenFileDialog(); dlg.Title="打开"; dlg.Filter="BMP(*.BMP)|*.bmp|JEPG(*.JPG;*.JEPG)|*.jpg;*.jepg|所有文件(*.*)|*.*"; dlg.FilterIndex=2; if(dlg.ShowDialog()==DialogResult.OK) { if(this.m_Bitmap!=null) { this.m_Bitmap=null; } try { this.m_Bitmap=new Bitmap(dlg.FileName); this.pictureBox1.Image=this.m_Bitmap; // this.pictureBox1.Visible=false; // Graphics g=this.CreateGraphics(); // g.DrawImage(this.m_Bitmap,-100,100); } catch(Exception e001) { MessageBox.Show("打开图片失败!\n" e001.Message); return; } } } /// <summary> /// 存储为 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void menuSaveAs_Click(object sender, System.EventArgs e) { SaveFileDialog dlg=new SaveFileDialog(); dlg.Filter="BMP(*.BMP)|*.bmp|JEPG(*.JPG;*.JEPG)|*.jpg;*.jepg|所有文件(*.*)|*.*"; if(dlg.ShowDialog()==DialogResult.OK) { switch(dlg.FilterIndex) { case 1: this.pictureBox1.Image.Save(dlg.FileName,ImageFormat.Bmp); break; case 2: this.pictureBox1.Image.Save(dlg.FileName,ImageFormat.Jpeg); break; default: this.pictureBox1.Image.Save(dlg.FileName,ImageFormat.Bmp); break; } } } private void menuFile_Popup(object sender, System.EventArgs e) { bool b_map=(this.pictureBox1.Image!=null); this.menuSave.Enabled=b_map; this.menuSaveAs.Enabled=b_map; } /// <summary> /// 在弹出子菜单之前更新子菜单的UI状态 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void menuFilter_Popup(object sender, EventArgs e) { bool b_map=(this.pictureBox1.Image!=null); this.menuDisplace.Enabled=b_map; this.menuInvert.Enabled=b_map; this.mnDrawWatermark.Enabled = b_map; this.mnWatermark2.Enabled = b_map; } /// <summary> /// 反相的菜单处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void menuInvert_Click(object sender, System.EventArgs e) { Bitmap bm=(Bitmap)(this.pictureBox1.Image); //锁定内存 BitmapData bmData1=bm.LockBits(new Rectangle(0,0,bm.Width,bm.Height), ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb); //每个像素占3个字节(24位) int stride=bmData1.Stride; //扫描行宽度(字节,是4的倍数) System.IntPtr scan0=bmData1.Scan0; //第一个像素数据的地址 unsafe { byte* p=(byte*)(void*)scan0; int nOffset=stride-bm.Width*3; //扫描行尾部的补0的字节数 int nWidth=bm.Width*3; //扫描行宽度=像素宽度的3倍,扫描行高度=像素高度 for(int j=0;j<bm.Height;j ) { for(int i=0;i<nWidth;i ) { p[0]=(byte)(255-p[0]); //移动指针 p ; } p =nOffset; //换到下一行 } } bm.UnlockBits(bmData1); this.pictureBox1.Invalidate(); //Invalidate会立即强制更新显存内容,而update只有在下一次绘制显存时才会更新 } /// <summary> /// 置换处理 /// </summary> /// <param name="bm1">原图</param> /// <param name="bm2">置换图</param> /// <returns>返回置换的结果</returns> private Bitmap DispaceUnsafe(Bitmap bm1,Bitmap bm2) { //创建返回的结果bm4 Bitmap bm4=new Bitmap(bm1.Width,bm1.Height); //将置换图bm2伸展或拼贴到与bm1一致的bm3 Bitmap bm3=this.CreateCompatibleBitmap(bm1,bm2); //原图bm1锁定内存(只读) BitmapData bmData1=bm1.LockBits(new Rectangle(0,0,bm1.Width,bm1.Height), ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb); //锁定伸展拼贴后的置换图bm3数据(只读) BitmapData bmData3=bm3.LockBits(new Rectangle(0,0,bm3.Width,bm3.Height), ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb); //结果图锁定内存(只写) BitmapData bmData4=bm4.LockBits(new Rectangle(0,0,bm4.Width,bm4.Height), ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb); //扫描行宽度(字节)=位图宽度(像素)*bpp/8 行尾补0字节数 (bpp:色深度,位/像素) int stride=bmData1.Stride; //得到三个位图的象素数组在内存中的起始地址 IntPtr scan0_1=bmData1.Scan0; IntPtr scan0_3=bmData3.Scan0; IntPtr scan0_4=bmData4.Scan0; unsafe { byte* p1=(byte*)(void*)scan0_1; //原图的第一个像素数据地址 byte* p3=(byte*)(void*)scan0_3; //一致的置换图... byte* p4=(byte*)(void*)scan0_4; //待返回的结果图... int imax=bm1.Width; int jmax=bm1.Height; int dx,dy,x,y; //i,j以像素为单位(每个像素的数据占3个字节,地址由低到高顺序:[Blue Green Red] ) if(this.b_Repeat) { //未定义区域:重复边缘像素方式 for(int j=0;j<jmax;j ) for(int i=0;i<imax;i ) { dx=(int)(this.m_X/100*(p3[i*3 j*stride 2]-128)); //像素起始位置 2=R dy=(int)(this.m_Y/100*(p3[i*3 j*stride 1]-128)); //像素起始位置 1=G x=i dx; y=j dy; //重复边缘象素(取已知区域的边缘,即0,imax-1,jmax-1) if(x>imax-1) x=imax-1; else if(x<0) x=0; if(y>jmax-1) y=jmax-1; else if(y<0) y=0; //将原图[x,y]位置处的像素数据复制到结果图[i,j]处 p4[i*3 j*stride]=p1[x*3 y*stride]; //B p4[i*3 j*stride 1]=p1[x*3 y*stride 1]; //G p4[i*3 j*stride 2]=p1[x*3 y*stride 2]; //R } } else { //未定义区域:折回方式 for(int j=0;j<jmax;j ) for(int i=0;i<imax;i ) { dx=(int)(this.m_X/100*(p3[i*3 j*stride 2]-128)); //像素起始位置 2=R dy=(int)(this.m_Y/100*(p3[i*3 j*stride 1]-128)); //像素起始位置 1=G x=i dx; y=j dy; //折回到已知区域 if(x>imax-1) x=x%imax; //位于原图右侧时取余数 else if(x<0) x=imax-((-x)%imax); if(y>jmax-1) y=y%jmax; else if(y<0) y=jmax-((-y)%jmax); //将原图[x,y]位置处的像素数据复制到结果图[i,j]处 p4[i*3 j*stride]=p1[x*3 y*stride]; //B p4[i*3 j*stride 1]=p1[x*3 y*stride 1]; //G p4[i*3 j*stride 2]=p1[x*3 y*stride 2]; //R } } } //解锁所有位图的内存 bm1.UnlockBits(bmData1); bm3.UnlockBits(bmData3); bm4.UnlockBits(bmData4); return bm4; } /// <summary> /// 置换处理 /// </summary> /// <param name="bm1">原图</param> /// <param name="bm2">置换图</param> /// <returns>返回置换的结果</returns> private Bitmap Dispace(Bitmap bm1,Bitmap bm2) { //创建返回的结果bm4 Bitmap bm4=new Bitmap(bm1.Width,bm1.Height); //将置换图bm2伸展或拼贴到与bm1一致的bm3 Bitmap bm3=this.CreateCompatibleBitmap(bm1,bm2); int imax=bm1.Width; int jmax=bm1.Height; int dx,dy,x,y; for(int i=0;i<imax;i ) { for(int j=0;j<jmax;j ) { dx=(int)(this.m_X*0.01*(bm3.GetPixel(i,j).R-128)); dy=(int)(this.m_Y*0.01*(bm3.GetPixel(i,j).G-128)); x=i dx; y=j dy; if(this.b_Repeat) { //重复边缘象素 if(x>imax-1) x=imax-1; else if(x<0) x=0; if(y>jmax-1) y=jmax-1; else if(y<0) y=0; } else { //折回方式 while(x>imax-1) { x-=imax-1; } while(x<0) { x =imax; } while(y>jmax-1) { y-=jmax-1; } while(y<0) { y =jmax; } } bm4.SetPixel(i,j,bm1.GetPixel(x,y)); } } return bm4; } /// <summary> /// 将置换图创建为和原图相同大小的用于计算的图 /// </summary> /// <param name="bm1">原图</param> /// <param name="bm2">置换图</param> /// <returns></returns> private Bitmap CreateCompatibleBitmap(Bitmap bm1,Bitmap bm2) { //创建返回的结果 Bitmap bm3=new Bitmap(bm1.Width,bm1.Height); Graphics g3=Graphics.FromImage(bm3); if(this.b_Stretch) { //伸展以适合 g3.DrawImage(bm2, new Rectangle(0,0,bm1.Width,bm1.Height), 0,0,bm2.Width,bm2.Height, GraphicsUnit.Pixel); } else { //拼贴,拼贴次数 1,为了保证能够覆盖完全 int imax=bm1.Width/bm2.Width 1; int jmax=bm1.Height/bm2.Height 1; for(int i=0;i<imax;i ) { for(int j=0;j<jmax;j ) { g3.DrawImage(bm2, new Rectangle(bm2.Width*i,bm2.Height*j,bm2.Width,bm2.Height), 0,0,bm2.Width,bm2.Height, GraphicsUnit.Pixel); } } } //返回伸展或者拼贴后的置换图 return bm3; } /// <summary> /// 生成缩放置换图菜单的处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void menuCreateZoomBM_Click(object sender, System.EventArgs e) { this.m_Bitmap = this.CreateZoomBM(); this.pictureBox1.Image=this.m_Bitmap; this.pictureBox1.Invalidate(); } /// <summary> /// 生成缩放置换图,(特点:边缘不移动) /// </summary> /// <returns></returns> private Bitmap CreateZoomBM() { Bitmap bm=new Bitmap(356,356); int r,g; for(int i=0;i<356;i ) { r=128; g=128; for(int j=0;j<356;j ) { //左上角 if(i<50 && j<50) { r=(int)(i*j*127/2500.0 128); g=(int)(i*j*127/2500.0 128); } //左中部 else if(i<50 && j>49 && j<306) { r=(int)(i*127/50.0 128); g=(int)(i*((305-j)-128)/50.0 128); } //右中部 else if(i>305 && j>49 && j<306) { r=(int)((i-355)*127/50.0 128); g=(int)((355-i)*((305-j)-128)/50.0 128); } //上中部 else if(i>49 && i<306 && j<50) { r=(int)(j*((305-i)-128)/50.0 128); g=(int)(j*127/50.0 128); } //下中部 else if(i>49 && i<306 && j>306) { r=(int)((355-j)*((305-i)-128)/50.0 128); g=(int)((j-355)*127/50.0 128); } //右下角 else if(i>305 && j>305) { r=(int)((i-355)*(355-j)*127/2500.0 128); g=(int)((i-355)*(355-j)*127/2500.0 128); } //中间精确置换图 else if(j>49 && j<306 && i>49 && i<306) { r=305-i; g=305-j; } //右上角 else if(i>305 && j<50) { r=(int)((i-355)*j*127/2500.0 128); g=(int)((355-i)*j*127/2500.0 128); } //左下角 else if(i<50 && j>305) { r=(int)((355-j)*i*127/2500.0 128); g=(int)((j-355)*i*127/2500.0 128); } bm.SetPixel(i,j,Color.FromArgb(r,g,255)); } } return bm; } /// <summary> /// 调节色阶 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void menuAdjustLevel_Click(object sender, System.EventArgs e) { AdjustLevelDlg dlg=new AdjustLevelDlg(); dlg.ShowDialog(); } /// <summary> /// 生成水波特效置换图 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mnCreateWaveBm_Click(object sender, System.EventArgs e) { NewWaterEffDlg dlg0=new NewWaterEffDlg(); if(dlg0.ShowDialog()==DialogResult.OK) { WaterEffectDlg dlg1=new WaterEffectDlg(dlg0.BitmapWidth,dlg0.BitmapHeight); dlg1.Show(); } } /// <summary> /// 给一个位图绘制水印文字(没有验证水印是否超出图片边界!) /// </summary> /// <param name="text">水印文本</param> /// <param name="x">起始点</param> /// <param name="y">起始点</param> /// <param name="opacity">不透明度,0~1</param> private Bitmap DrawWatermark(Image image,string text, Font font,Brush brush,int x,int y,double opacity) { Bitmap bm1 = new Bitmap(image); Graphics g1=Graphics.FromImage(bm1); //测量水印文字的大小,然后申请一个新的位图 SizeF sizef=g1.MeasureString(text,font); Bitmap bm2=new Bitmap((int)sizef.Width,(int)sizef.Height); Graphics g2=Graphics.FromImage(bm2); g2.DrawImage(bm1, 0,0,new Rectangle(x, y, bm2.Width, bm2.Height),GraphicsUnit.Pixel); g2.DrawString(text,font,brush,0,0); BitmapData data1=bm1.LockBits(new Rectangle(0,0,bm1.Width,bm1.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb); BitmapData data2=bm2.LockBits(new Rectangle(0,0,bm2.Width,bm2.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb); unsafe { byte* p1=(byte*)(void*)data1.Scan0; byte* p2=(byte*)(void*)data2.Scan0; for(int j=0;j<bm2.Height;j ) { for(int i=0;i<bm2.Width*3;i ) { p1[(y j)*data1.Stride i]=(byte)(p1[(y j)*data1.Stride i]*(1-opacity) opacity*p2[j*data2.Stride i]); } } bm1.UnlockBits(data1); bm2.UnlockBits(data2); } return bm1; } /// <summary> /// 绘制水印(图片) /// </summary> /// <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 bm1 = new Bitmap(image); Bitmap bm2 = new Bitmap(wmImg.Width, wmImg.Height); Graphics g2 = Graphics.FromImage(bm2); ImageAttributes att = new ImageAttributes(); att.SetColorKey(key, key, ColorAdjustType.Bitmap); g2.DrawImage(bm1, 0, 0, new Rectangle(x, y, bm2.Width, bm2.Height), GraphicsUnit.Pixel); g2.DrawImage(wmImg, new Rectangle(0,0,bm2.Width,bm2.Height),0, 0,bm2.Width,bm2.Height,GraphicsUnit.Pixel,att); g2.Dispose(); BitmapData data1 = bm1.LockBits(new Rectangle(0, 0, bm1.Width, bm1.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData data2 = bm2.LockBits(new Rectangle(0, 0, bm2.Width, bm2.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); unsafe { byte* p1 = (byte*)(void*)data1.Scan0; byte* p2 = (byte*)(void*)data2.Scan0; for (int j = 0; j < bm2.Height; j ) { for (int i = 0; i < bm2.Width * 3; i ) { p1[(y j) * data1.Stride i] = (byte)(p1[(y j) * data1.Stride i] * (1 - opacity) opacity * p2[j * data2.Stride i]); } } bm1.UnlockBits(data1); bm2.UnlockBits(data2); } return bm1; } /// <summary> /// 给位图绘制水印 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mnDrawWatermark_Click(object sender, EventArgs e) { if (this.m_Bitmap == null) return; Bitmap bm=this.DrawWatermark(this.m_Bitmap,"ABCD~", new Font("Arial",20,FontStyle.Bold), Brushes.Red, 5, 15, 0.4); this.pictureBox1.Image = bm; this.pictureBox1.Invalidate(); } /// <summary> /// 绘制图片水印 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mnWatermark2_Click(object sender, EventArgs e) { if (this.m_Bitmap == null) return; Bitmap bm = new Bitmap(100, 100); Graphics g = Graphics.FromImage(bm); g.FillRectangle(Brushes.Magenta,0,0,bm.Width,bm.Height); g.FillEllipse(Brushes.Green, 10, 10, 50, 30); g.DrawString("图片水印",this.Font,Brushes.Blue,20,20); g.Dispose(); Bitmap bm2 = this.DrawWatermark(this.m_Bitmap, bm, Color.Magenta, 10, 15, 0.6); this.pictureBox1.Image = bm2; this.pictureBox1.Invalidate(); } //////////////////////////// Border /////////////////////////////////// } }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论