切割图片:
public Image CutImage(Image img, Rectangle rect) { Image destImg = new Bitmap(rect.Width,rect.Height); Graphics g = Graphics.FromImage(destImg); Rectangle destRect=new Rectangle(0,0,rect.Width,rect.Height); g.DrawImage(img, destRect, rect, GraphicsUnit.Pixel); return destImg;
} 使用Graphics.DrawImgage方法, 这个方法是把源图片指定的位置绘制到目标区域上. 注意:当源图片区域跟目标区域长宽比不等时图片将被拉缩,等比例不等值时可以实现缩略图,等值(长和宽)时就是切割了. -------------------------------------------- 半透明水印: 参考资料:给图片加透明度水印的方法(c#) 像素拷贝用Marchal.Copy,注意字节跌加时的偏移量 需要导入的命名空间 srcImg是底图,destImg是logo using System.Drawing.Imaging; using System.Drawing.Drawing2D; using System.Runtime.InteropServices;
public Image WaterMark(Bitmap srcImg, Bitmap destImg, double opacity) { int ypos = (int)((srcImg.Height * .99) - destImg.Height); int xpos = (int)((srcImg.Width * .99) - destImg.Width); BitmapData srcBD = srcImg.LockBits(new Rectangle(0,0,srcImg.Width,srcImg.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData destBD = destImg.LockBits(new Rectangle(0, 0, destImg.Width, destImg.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); IntPtr srcPtr = srcBD.Scan0; IntPtr destPtr = destBD.Scan0;
int srcLength = srcBD.Stride * srcBD.Height; int destLength = destBD.Stride * destBD.Height; byte[] srcBytes = new byte[srcLength]; byte[] destBytes = new byte[destLength];
Marshal.Copy(srcPtr, srcBytes, 0, srcLength); Marshal.Copy(destPtr, destBytes, 0, destLength);
for (int y = 0; y < destBD.Height; y++) { for (int x = 0; x < destBD.Stride; x++) { srcBytes[(ypos + y) * (srcBD.Stride) + xpos * 3 + x] = (byte)(srcBytes[(ypos + y) * (srcBD.Stride) + xpos * 3 + x] * (1 - opacity) + destBytes[y * (destBD.Stride) + x] * opacity); } }
Marshal.Copy(srcBytes, 0, srcPtr, srcLength); destImg.UnlockBits(destBD); srcImg.UnlockBits(srcBD); return srcImg; }
文字透明水印:
--------------------------
public Image WaterMark(Bitmap srcImg, string text, double opacity) { //寻找合适的字体大小 Graphics g = Graphics.FromImage(srcImg); int[] fontSizes =new int[] {24,22,20,18,16,14,12,10,8,6,4}; Font font=null; SizeF size=new SizeF(); for (int i = 0; i < fontSizes.Length; i++) { //字体,以及字体样式(加粗,斜体,下划线等) font = new Font("Arial", fontSizes[i], FontStyle.Bold); size = g.MeasureString(text, font); if ((ushort)size.Width < (ushort)srcImg.Width) break; } g.Dispose();
//右下方 int ypos =(int)((srcImg.Height * .99) - (int) size.Height); int xpos =(int)((srcImg.Width * .99) - (int)size.Width ); Bitmap bmp = new Bitmap((int)size.Width,(int) size.Height); Graphics pic = Graphics.FromImage(bmp); pic.SmoothingMode=SmoothingMode.AntiAlias; pic.DrawImage(srcImg, new Rectangle(0, 0,bmp.Width,bmp.Height), new Rectangle(xpos, ypos,bmp.Width,bmp.Height), GraphicsUnit.Pixel); Brush brush=new SolidBrush(Color.WhiteSmoke); pic.DrawString(text, font, brush, 0, 0); brush.Dispose(); //透明度处理 Rectangle srcRect=new Rectangle(0,0,srcImg.Width,srcImg.Height); BitmapData srcBD = srcImg.LockBits(srcRect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData destBD = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
IntPtr srcPtr = srcBD.Scan0; IntPtr destPtr = destBD.Scan0;
int srcLength = srcBD.Stride * srcBD.Height ; int destLength =destBD.Stride * destBD.Height ; byte[] srcBytes = new byte[srcLength]; byte[] destBytes = new byte[destLength];
Marshal.Copy(srcPtr, srcBytes, 0, srcLength); Marshal.Copy(destPtr, destBytes, 0, destLength); for (int y = 0; y < destBD.Height; y++) { for (int x = 0; x { srcBytes[(ypos + y) * (srcBD.Stride) +xpos * 3 + x] = (byte)(srcBytes[(ypos + y) * (srcBD.Stride) + xpos * 3 + x] * (1 - opacity) + destBytes[y * (destBD.Stride) + x ] * opacity); } } Marshal.Copy(srcBytes, 0, srcPtr,srcLength); bmp.UnlockBits(destBD); srcImg.UnlockBits(srcBD);
return srcImg;
}
---------------------
图片等比例缩略图: 说明,先将图片剪切,再等比例缩小,这样图片不变形,另外小图片质量比GetThumbnailImage方法要清晰点,
public static bool Thum(string srcPath, string destPath, double width, double height) { System.Drawing.Image img = new Bitmap(srcPath); //生成图片大小必需小于原图 if (img.Width < width) { width = img.Width;
} if (img.Height < height) { height = img.Height; } //删除的高度,与宽度 double cutWidth, cutHeight; cutWidth = (img.Width * height / img.Height - width); //宽度切割,高度缩放 cutHeight = (img.Height * width / img.Width - height);//高度切割,宽度缩放 byte flag = 0;//0 截高,1 截宽 //这里的截宽是指缩略图的宽将被截,不是指原图, //1. 按原图比例,选择缩略图的高固定,计算出来的宽如果大于指定的宽,那么就按高固定,计算出来的宽来生成缩略图,再按给定大小截取 //2. 按原图比例,选择缩略图的宽固定,计算出来的高如果大于指定的高,那么就按宽固定,计算出来的高来生成缩略图,再按给定大小截取 //3. 因为长宽比只能取{1,>1,<1}三种情况 flag = (byte)(cutHeight <= cutWidth ? 0 : 1);
//System.Drawing.Image.GetThumbnailImageAbort myCallback=new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback); System.Drawing.Image thumImg; if (flag == 0) thumImg = new Bitmap(img, (int)width, (int)height + (int)cutHeight); //img.GetThumbnailImage((int)width, (int)height + (int)cutHeight, myCallback, IntPtr.Zero); else thumImg = new Bitmap(img, (int)width + (int)cutWidth, (int)height);// img.GetThumbnailImage((int)width + (int)cutWidth, (int)height, myCallback, IntPtr.Zero); System.Drawing.Bitmap destImg = new Bitmap((int)width, (int)height); Graphics g = Graphics.FromImage(destImg); Rectangle rect = new Rectangle(0, 0, (int)width, (int)height); //填充透明背景 g.FillRectangle(Brushes.White,rect);
g.DrawImage(thumImg, rect, rect, GraphicsUnit.Pixel); g.Save(); destImg.Save(destPath, GetFormat(destPath)); thumImg.Dispose(); img.Dispose(); destImg.Dispose(); return true; }