实例介绍
【实例简介】
【实例截图】
【核心代码】
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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论