C#實現圖片縮放(包括縮圖和旋轉)
阿新 • • 發佈:2019-02-14
using System; using System.Collections; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Web; using System.Web.UI.HtmlControls; namespace HS.Comm.Utility { /// <summary> /// 水印位置 /// </summary> public enum ImagePosition { /// <summary> /// 預設 /// </summary> Default = 1, /// <summary> /// 左上 /// </summary> LeftTop = 2, /// <summary> /// 左下 /// </summary> LeftBottom = 3, /// <summary> /// 右上 /// </summary> RightTop = 4, /// <summary> /// 右下 /// </summary> RigthBottom = 5, //TopMiddle, //頂部居中 //BottomMiddle, //底部居中 //Center //中心 } /// <summary> /// ImageUtil 的摘要說明。 /// </summary> public class ImageUtil { /// <summary> /// 建構函式 /// </summary> public ImageUtil() { // // TODO: 在此處新增建構函式邏輯 // } /// <summary> /// 生成縮圖 /// </summary> /// <param name="originalImagePath">源圖路徑(物理路徑)</param> /// <param name="thumbnailPath">縮圖路徑(物理路徑)</param> /// <param name="width">縮圖寬度</param> /// <param name="height">縮圖高度</param> /// <param name="mode">生成縮圖的方式</param> /// <param name="isaddwatermark">是否新增水印</param> /// <param name="quality">圖片品質</param> public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode = "Cut", bool isaddwatermark = false, int quality = 75) { MakeThumbnail(originalImagePath, thumbnailPath, width, height, mode, isaddwatermark, ImagePosition.Default, null, quality); } /// <summary> /// 生成縮圖 /// </summary> /// <param name="originalImagePath">源圖路徑(物理路徑)</param> /// <param name="thumbnailPath">縮圖路徑(物理路徑)</param> /// <param name="width">縮圖寬度</param> /// <param name="height">縮圖高度</param> /// <param name="mode">生成縮圖的方式</param> /// <param name="isaddwatermark">是否新增水印</param> /// <param name="quality">圖片品質</param> /// <param name="imagePosition">水印位置</param> /// <param name="waterImage">水印圖片名稱</param> public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode, bool isaddwatermark, ImagePosition imagePosition, string waterImage = null, int quality = 75) { Image originalImage = Image.FromFile(originalImagePath); int towidth = width; int toheight = height; int x = 0; int y = 0; int ow = originalImage.Width; int oh = originalImage.Height; switch (mode) { case "HW"://指定高寬縮放(可能變形) break; case "W"://指定寬,高按比例 toheight = originalImage.Height * width / originalImage.Width; break; case "H"://指定高,寬按比例 towidth = originalImage.Width * height / originalImage.Height; break; case "Cut"://指定高寬裁減(不變形) if (originalImage.Width >= towidth && originalImage.Height >= toheight) { if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight) { oh = originalImage.Height; ow = originalImage.Height * towidth / toheight; y = 0; x = (originalImage.Width - ow) / 2; } else { ow = originalImage.Width; oh = originalImage.Width * height / towidth; x = 0; y = (originalImage.Height - oh) / 2; } } else { x = (originalImage.Width - towidth) / 2; y = (originalImage.Height - toheight) / 2; ow = towidth; oh = toheight; } break; case "Fit"://不超出尺寸,比它小就不截了,不留白,大就縮小到最佳尺寸,主要為手機用 if (originalImage.Width > towidth && originalImage.Height > toheight) { if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight) toheight = originalImage.Height * width / originalImage.Width; else towidth = originalImage.Width * height / originalImage.Height; } else if (originalImage.Width > towidth) { toheight = originalImage.Height * width / originalImage.Width; } else if (originalImage.Height > toheight) { towidth = originalImage.Width * height / originalImage.Height; } else { towidth = originalImage.Width; toheight = originalImage.Height; ow = towidth; oh = toheight; } break; default: break; } //新建一個bmp圖片 Image bitmap = new System.Drawing.Bitmap(towidth, toheight); //新建一個畫板 Graphics g = System.Drawing.Graphics.FromImage(bitmap); //設定高質量插值法 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; //設定高質量,低速度呈現平滑程度 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; //清空畫布並以透明背景色填充 g.Clear(Color.White); //在指定位置並且按指定大小繪製原圖片的指定部分 g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight), new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel); //加圖片水印 if (isaddwatermark) { if (string.IsNullOrEmpty(waterImage)) waterImage = "watermarker.png"; Image copyImage = System.Drawing.Image.FromFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, waterImage)); //g.DrawImage(copyImage, new Rectangle(bitmap.Width-copyImage.Width, bitmap.Height-copyImage.Height, copyImage.Width, copyImage.Height), 0, 0, copyImage.Width, copyImage.Height, GraphicsUnit.Pixel); int xPosOfWm; int yPosOfWm; int wmHeight = copyImage.Height; int wmWidth = copyImage.Width; int phHeight = toheight; int phWidth = towidth; switch (imagePosition) { case ImagePosition.LeftBottom: xPosOfWm = 70; yPosOfWm = phHeight - wmHeight - 70; break; case ImagePosition.LeftTop: xPosOfWm = 70; yPosOfWm = 0 - 70; break; case ImagePosition.RightTop: xPosOfWm = phWidth - wmWidth - 70; yPosOfWm = 0 - 70; break; case ImagePosition.RigthBottom: xPosOfWm = phWidth - wmWidth - 70; yPosOfWm = phHeight - wmHeight - 70; break; default: xPosOfWm = 10; yPosOfWm = 0; break; } g.DrawImage(copyImage, new Rectangle(xPosOfWm, yPosOfWm, copyImage.Width, copyImage.Height), 0, 0, copyImage.Width, copyImage.Height, GraphicsUnit.Pixel); } // 以下程式碼為儲存圖片時,設定壓縮質量 EncoderParameters encoderParams = new EncoderParameters(); long[] qualityArray = new long[1]; qualityArray[0] = quality; EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityArray); encoderParams.Param[0] = encoderParam; //獲得包含有關內建影象編碼解碼器的資訊的ImageCodecInfo 物件. ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo jpegICI = null; for (int i = 0; i < arrayICI.Length; i++) { if (arrayICI[i].FormatDescription.Equals("JPEG")) { jpegICI = arrayICI[i]; //設定JPEG編碼 break; } } try { if (jpegICI != null) { bitmap.Save(thumbnailPath, jpegICI, encoderParams); } else { //以jpg格式儲存縮圖 bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg); } } catch { throw; } finally { originalImage.Dispose(); bitmap.Dispose(); g.Dispose(); } } #region 圖片旋轉函式 /// <summary> /// 以逆時針為方向對影象進行旋轉 /// </summary> /// <param name="b">點陣圖流</param> /// <param name="angle">旋轉角度[0,360](前臺給的)</param> /// <returns></returns> public static Image RotateImg(Image b, int angle, string targetFileName) { angle = angle % 360; //弧度轉換 double radian = angle * Math.PI / 180.0; double cos = Math.Cos(radian); double sin = Math.Sin(radian); //原圖的寬和高 int w = b.Width; int h = b.Height; int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin))); int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos))); //目標點陣圖 Bitmap dsImage = new Bitmap(W, H); System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dsImage); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //計算偏移量 Point Offset = new Point((W - w) / 2, (H - h) / 2); //構造影象顯示區域:讓影象的中心與視窗的中心點一致 Rectangle rect = new Rectangle(Offset.X, Offset.Y, w, h); Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2); g.TranslateTransform(center.X, center.Y); g.RotateTransform(360 - angle); //恢復影象在水平和垂直方向的平移 g.TranslateTransform(-center.X, -center.Y); g.DrawImage(b, rect); //重至繪圖的所有變換 g.ResetTransform(); g.Save(); g.Dispose(); //儲存旋轉後的圖片 b.Dispose(); dsImage.Save(targetFileName, System.Drawing.Imaging.ImageFormat.Jpeg); return dsImage; } public static Image RotateImg(string filename, int angle, string targetFileName) { return RotateImg(GetSourceImg(filename), angle, targetFileName); } public static Image GetSourceImg(string filename) { Image img; img = Bitmap.FromFile(filename); return img; } #endregion 圖片旋轉函式 } }