1. 程式人生 > >C#實現圖片縮放(包括縮圖和旋轉)

C#實現圖片縮放(包括縮圖和旋轉)

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 圖片旋轉函式 
    }
}