MVC 采用 HttpPostedFileBase 压缩保存图片

一、帮助类库

using System;
using System.IO;

namespace Utity.ImgHelper
{
    /// <summary>
    /// Path utility functions<br/>
    /// 路径的工具函数<br/>
    /// </summary>
    public static class PathUtils
    {
        /// <summary>
        /// Secure path combining<br/>
        /// Throw exception if any part contains ".." or other invalid value<br/>
        /// 安全的合并路径<br/>
        /// 如果路径中有..或其他不合法的值则抛出例外<br/>
        /// </summary>
        /// <param name="paths">Path parts</param>
        /// <returns></returns>
        /// <example>
        /// <code language="cs">
        /// PathUtils.SecureCombine("a", "b", "c") == Path.Combine("a", "b", "c")
        /// PathUtils.SecureCombine("a", "/b", "c") throws exception
        /// PathUtils.SecureCombine("a", "\\b", "c") throws exception
        /// PathUtils.SecureCombine("a", "", "c") throws exception
        /// PathUtils.SecureCombine("a", "..", "c") throws exception
        /// PathUtils.SecureCombine("a/../b", "c") throws exception
        /// </code>
        /// </example>
        public static string SecureCombine(params string[] paths)
        {
            for (var i = 0; i < paths.Length; ++i)
            {
                var path = paths[i];
                if (i > 0 && path.StartsWith("/"))
                {
                    throw new ArgumentException($"path startswith '/'");
                }
                else if (path.StartsWith("\\"))
                {
                    throw new ArgumentException($"path startswith '\'");
                }
                else if (string.IsNullOrEmpty(path))
                {
                    throw new ArgumentException($"path {path} is null or empty");
                }
                else if (path.Contains(".."))
                {
                    throw new ArgumentException($"path {path} contains '..'");
                }
            }
            return Path.Combine(paths);
        }

        /// <summary>
        /// Ensure parent directories are exist<br/>
        /// 确保路径的上级文件夹存在<br/>
        /// </summary>
        /// <param name="path">Path</param>
        /// <example>
        /// <code language="cs">
        /// PathUtils.EnsureParentDirectory("c:\abc\123.txt");
        /// // will create c:\abc if not exist
        /// </code>
        /// </example>
        public static void EnsureParentDirectory(string path)
        {
            var parentDirectory = Path.GetDirectoryName(path);
            if (!Directory.Exists(parentDirectory))
            {
                Directory.CreateDirectory(parentDirectory);
            }
        }
    }
}
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;

namespace Utity.ImgHelper
{
    public static class ImageExtensions
    {

        /// <summary>
        /// Resize image
        /// </summary>
        /// <param name="image">Original image</param>
        /// <param name="width">Width</param>
        /// <param name="height">height</param>
        /// <param name="mode">Resize mode</param>
        /// <param name="background">Background default is transparent</param>
        /// <returns></returns>
        public static Image Resize(this Image image,
            int width, int height, ImageResizeMode mode, Color? background = null)
        {
            var src = new Rectangle(0, 0, image.Width, image.Height);
            var dst = new Rectangle(0, 0, width, height);
            // Calculate destination rectangle by resize mode
            if (mode == ImageResizeMode.Fixed)
            {
            }
            else if (mode == ImageResizeMode.ByWidth)
            {
                height = (int)((decimal)src.Height / src.Width * dst.Width);
                dst.Height = height;
            }
            else if (mode == ImageResizeMode.ByHeight)
            {
                width = (int)((decimal)src.Width / src.Height * dst.Height);
                dst.Width = width;
            }
            else if (mode == ImageResizeMode.Cut)
            {
                if ((decimal)src.Width / src.Height > (decimal)dst.Width / dst.Height)
                {
                    src.Width = (int)((decimal)dst.Width / dst.Height * src.Height);
                    src.X = (image.Width - src.Width) / 2; // Cut left and right
                }
                else
                {
                    src.Height = (int)((decimal)dst.Height / dst.Width * src.Width);
                    src.Y = (image.Height - src.Height) / 2; // Cut top and bottom
                }
            }
            else if (mode == ImageResizeMode.Padding)
            {
                if ((decimal)src.Width / src.Height > (decimal)dst.Width / dst.Height)
                {
                    dst.Height = (int)((decimal)src.Height / src.Width * dst.Width);
                    dst.Y = (height - dst.Height) / 2; // Padding left and right
                }
                else
                {
                    dst.Width = (int)((decimal)src.Width / src.Height * dst.Height);
                    dst.X = (width - dst.Width) / 2; // Padding top and bottom
                }
            }
            // Draw new image
            var newImage = new Bitmap(width, height);
            using (var graphics = Graphics.FromImage(newImage))
            {
                // Set smoothing mode
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                // Set background color
                graphics.Clear(background ?? Color.Transparent);
                // Render original image with the calculated rectangle
                graphics.DrawImage(image, dst, src, GraphicsUnit.Pixel);
            }
            return newImage;
        }

        /// <summary>
        /// Save to jpeg with specified quality
        /// </summary>
        /// <param name="image">Image object</param>
        /// <param name="filename">File path, will automatic create parent directories</param>
        /// <param name="quality">Compress quality, 1~100</param>
        public static void SaveJpeg(this Image image, string filename, long quality)
        {
            PathUtils.EnsureParentDirectory(filename);
            var encoder = ImageCodecInfo.GetImageEncoders().First(
                c => c.FormatID == ImageFormat.Jpeg.Guid);
            var parameters = new EncoderParameters();
            parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            image.Save(filename, encoder, parameters);
        }

        /// <summary>
        /// Save to icon, see
        /// http://stackoverflow.com/questions/11434673/bitmap-save-to-save-an-icon-actually-saves-a-png
        /// </summary>
        /// <param name="image">Image object</param>
        /// <param name="filename">File path, will automatic create parent directories</param>
        public static void SaveIcon(this Image image, string filename)
        {
            PathUtils.EnsureParentDirectory(filename);
            using (var stream = new FileStream(filename, FileMode.Create))
            {
                // Header (ico, 1 photo)
                stream.Write(new byte[] { 0, 0, 1, 0, 1, 0 }, 0, 6);
                // Size
                stream.WriteByte(checked((byte)image.Width));
                stream.WriteByte(checked((byte)image.Height));
                // No palette
                stream.WriteByte(0);
                // Reserved
                stream.WriteByte(0);
                // No color planes
                stream.Write(new byte[] { 0, 0 }, 0, 2);
                // 32 bpp
                stream.Write(new byte[] { 32, 0 }, 0, 2);
                // Image data length, set later
                stream.Write(new byte[] { 0, 0, 0, 0 }, 0, 4);
                // Image data offset, fixed 22 here
                stream.Write(new byte[] { 22, 0, 0, 0 }, 0, 4);
                // Write png data
                image.Save(stream, ImageFormat.Png);
                // Write image data length
                long imageSize = stream.Length - 22;
                stream.Seek(14, SeekOrigin.Begin);
                stream.WriteByte((byte)(imageSize));
                stream.WriteByte((byte)(imageSize >> 8));
                stream.WriteByte((byte)(imageSize >> 16));
                stream.WriteByte((byte)(imageSize >> 24));
            }
        }

        /// <summary>
        /// Save image by it's file extension
        /// Quality parameter only available for jpeg
        /// </summary>
        /// <param name="image">Image object</param>
        /// <param name="filename">File path, will automatic create parent directories</param>
        /// <param name="quality">Compress quality, 1~100</param>
        public static void SaveAuto(this Image image, string filename, long quality)
        {
            PathUtils.EnsureParentDirectory(filename);
            var extension = Path.GetExtension(filename).ToLower();
            if (extension == ".jpg" || extension == ".jpeg")
            {
                image.SaveJpeg(filename, quality);
            }
            else if (extension == ".bmp")
            {
                image.Save(filename, ImageFormat.Bmp);
            }
            else if (extension == ".gif")
            {
                image.Save(filename, ImageFormat.Gif);
            }
            else if (extension == ".ico")
            {
                image.SaveIcon(filename);
            }
            else if (extension == ".png")
            {
                image.Save(filename, ImageFormat.Png);
            }
            else if (extension == ".tiff")
            {
                image.Save(filename, ImageFormat.Tiff);
            }
            else if (extension == ".exif")
            {
                image.Save(filename, ImageFormat.Exif);
            }
            else
            {
                throw new NotSupportedException(
                    string.Format("unsupport image extension {0}", extension));
            }
        }
    }

    /// <summary>
    /// Image resize mode
    /// </summary>
    public enum ImageResizeMode
    {
        /// <summary>
        /// Resize to the specified size, allow aspect ratio change
        /// </summary>
        Fixed,
        /// <summary>
        /// Resize to the specified width, height is calculated by the aspect ratio
        /// </summary>
        ByWidth,
        /// <summary>
        /// Resize to the specified height, width is calculated by the aspect ratio
        /// </summary>
        ByHeight,
        /// <summary>
        /// Resize to the specified size, keep aspect ratio and cut the overflow part
        /// </summary>
        Cut,
        /// <summary>
        /// Resize to the specified size, keep aspect ratio and padding the insufficient part
        /// </summary>
        Padding
    }
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Utity.ImgHelper
{
    /// <summary>
    /// 图片压缩类
    /// </summary>
    public class ImageHttpPostedFileBase : HttpPostedFileBase
    {
        Stream stream;
        string contentType;
        string fileName;
        public int ImageQuality { get; set; }
        public Size ImageThumbnailSize { get; set; }
        public ImageResizeMode ImageResizeMode { get; set; }
        public ImageHttpPostedFileBase(Stream stream, string contentType, string fileName, Size imageThumbnailSize, int ImageQuality, ImageResizeMode imageResizeMode)
        {
            this.stream = stream;
            this.contentType = contentType;
            this.fileName = fileName;
            this.ImageQuality = ImageQuality;
            this.ImageThumbnailSize = imageThumbnailSize;
            this.ImageResizeMode = imageResizeMode;

        }

        public override int ContentLength
        {
            get { return (int)stream.Length; }
        }

        public override string ContentType
        {
            get { return contentType; }
        }

        public override string FileName
        {
            get { return fileName; }
        }

        public override Stream InputStream
        {
            get { return stream; }
        }

        public override void SaveAs(string filename)
        {
            var image = Image.FromStream(stream);
            using (var thumbnailImage = image.Resize(ImageThumbnailSize.Width, ImageThumbnailSize.Height, ImageResizeMode, Color.White))
                thumbnailImage.SaveAuto(filename, ImageQuality);

        }

    }
}

使用:

ImageHttpPostedFileBase fileBase = new ImageHttpPostedFileBase(formFile.InputStream, formFile.ContentType, formFile.FileName, new Size(240, 200), 90, ImageResizeMode.ByWidth);
                fileBase.SaveAs(sSavedPath);

例子:

/// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="formFile"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult UpLoadImg(HttpPostedFileBase formFile)
        {
            var data = new MessageModel<string>();
            if (formFile == null)
            {
                data.success = false;
                data.msg = "图片保存失败";
                return Json(data);
            }
            string _path = "_FileUpLoad";
            //文件名
            var currentPictureWithoutExtension = Path.GetFileNameWithoutExtension(formFile.FileName);
            //扩展名
            var currentPictureExtension = Path.GetExtension(formFile.FileName).ToUpper();

            string savePath = Server.MapPath("~/" + _path) + "/" + DateTime.Now.ToString("yyyyMMdd") + "/";
            if (LimitPictureType.Contains(currentPictureExtension))
            {
                if (!Directory.Exists(savePath))
                {
                    Directory.CreateDirectory(savePath);
                }
                string _name = DateTime.Now.ToString("yyyyMMddHHmmss");

                #region 保存缩略图
                string sname = _name + "_thumb" + currentPictureExtension.ToLower();
                string sSavedPath = savePath + sname;
                ImageHttpPostedFileBase fileBase = new ImageHttpPostedFileBase(formFile.InputStream, formFile.ContentType, formFile.FileName, new Size(240, 200), 90, ImageResizeMode.ByWidth);
                fileBase.SaveAs(sSavedPath);
                #endregion
                
                string name = _name + currentPictureExtension.ToLower();
                string bSavePaht = savePath + name;
                formFile.SaveAs(bSavePaht);

                data.success = true;
                data.msg = "图片保存成功";
                //返回路径
                data.response = "/" + _path + "/" + DateTime.Now.ToString("yyyyMMdd") + "/" + name;
            }
            else
            {
                data.success = false;
                data.msg = "图片保存失败";
            }
            return Json(data);

        }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Model
{
    /// <summary>
    /// 通用返回信息类
    /// </summary>
    public class MessageModel<T>
    {
        /// <summary>
        /// 操作是否成功
        /// </summary>
        public bool success { get; set; } = false;
        /// <summary>
        /// 返回信息
        /// </summary>
        public string msg { get; set; } = "服务器异常";
        /// <summary>
        /// 返回数据集合
        /// </summary>
        public T response { get; set; }

    }
}

 

posted @ 2020-11-05 15:19  岳帅超  阅读(490)  评论(0编辑  收藏  举报