当前位置:编程学习 > C#/ASP.NET >>

待上传图片大小不一,上传后想显示同样大小的尺寸,且图片不变形,如何实现

需要上传的图片尺寸不一样,但是上传之后想显示同样大小的尺寸,而且图片不变形,该如何实现呢,很多汽车网站的图片大小都是一样的,但是上传图片的时候我想不应该都是上传的同样尺寸的图片吧,而且有的是让客户上传的图片,客户不同  他们上传的汽车图片肯定也不一样,但是显示出来确实是同样的尺寸,而且没有变形,该如何实现呢  急急急急!!!!!!!!!!!!!!!!!! 图片上传,固定尺寸不变形 --------------------编程问答-------------------- 简单的做法,当长宽比列与设置的比列不一致时,截取等比例的中间部分,再缩放处理 --------------------编程问答-------------------- 等比例缩放一下 --------------------编程问答--------------------
引用 2 楼 yumen3501 的回复:
等比例缩放一下
--------------------编程问答-------------------- 等比例缩放,
但是如果你定义的大小比原图还要大,图片要失真。 --------------------编程问答--------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
//此处BLL可以是自己项目的命名空间名称
namespace BLL
{
    public class Upload
    {
        /*上传图片并进行各种类型的处理,方法本身返回原图地址,如:2013408/P-14C46N25534U.jpg
        HttpPostedFile upFile:页面中上传控件做为参数传递至此
        NewTemp为上传根目录,如  "/upload/"
        iwidth:要裁剪或缩放的宽度
        iheight:要裁剪的高度
        ctype:缩放或裁剪类型,见下面方法描述
        smname:返回缩放或裁剪后的小图,如:2013408/P-14C46N25534U_s.jpg
        */
        public string UpImg(HttpPostedFile upFile, string NewTemp, int iwidth, int iheight, int ctype, ref string smname)
        {
            return SaveImg(upFile, NewTemp, iwidth, iheight, ctype, ref smname);
        }
        //上面方法的重载,不同的地方为smname返回的是空值,表示本调用不需要得到2个图片地址,方法本身返回原图或裁剪后的图片地址,如:2013408/P-14C46N25534U.jpg
        public string UpImg(HttpPostedFile upFile, string NewTemp, int iwidth, int iheight, int ctype)
        {
            string smname = "";
            return SaveImg(upFile, NewTemp, iwidth, iheight, ctype, ref smname);
        }

        /*上传图片,返回值为上传的图片原图地址  by alun
         * iwidth:准备裁剪缩放的宽,可为0
         * iheight:准备裁剪缩放的高,可为0
         * smname:有时需要将小图地址返回
         * ctype参数:
         * 0不裁剪不缩放,直接保存图片
         * 1按iwidth缩放,不裁剪,然后覆盖原图
         * 2按iwidth缩放,不裁剪,不覆盖原图,方法返回大图地址,smname参数返回缩放后的小图地址
         * 3按iwidth和iheight裁剪并缩放,覆盖原图
         * 4按iwidth和iheight裁剪并缩放,不覆盖原图,方法返回大图地址,smname参数返回缩放后的小图地址
        */
        public string SaveImg(HttpPostedFile upFile, string NewTemp, int iwidth, int iheight, int ctype, ref string smname)
        {
            string extName = Path.GetExtension(upFile.FileName).ToLower();
            if (extName == "") return "";
            string Passtr = ".gif.jpg.bmp.png.jpeg";
            if (Passtr.Contains(extName))
            {
                //按日期建文件夹,返回的文件路径不包含传来的"/upload/"
                string DateFolder = DateTime.Now.ToString("yyyyMM") + "/";
                string filename = DateFolder + CreateFileName("P") + extName;
                smname = DateFolder + CreateFileName("P") + "_s" + extName;
                string newFilePath = HttpContext.Current.Server.MapPath(NewTemp);
                CreateForder(newFilePath);
                CreateForder(newFilePath + DateFolder);
                try
                {
                    string bigpic = newFilePath + filename;
                    string smpic = newFilePath + smname;
                    Bitmap bmp = new Bitmap(upFile.InputStream);
                    if (IsCMYK(bmp)) bmp = ConvertCMYK(bmp);
                    switch (ctype)
                    {
                        case 0: bmp.Save(bigpic); break;
                        case 1: SmallPicHeight(bmp, bigpic, iwidth); break;
                        case 2: bmp.Save(bigpic); SmallPicHeight(bmp, smpic, iwidth); break;
                        case 3: CutForCustom(bmp, bigpic, iwidth, iheight, 50); break;
                        case 4: bmp.Save(bigpic); CutForCustom(bmp, smpic, iwidth, iheight, 50); break;
                    }
                    bmp.Dispose();
                    NewTemp = filename;
                }
                catch
                {
                    NewTemp = "";
                }
                upFile = null;
                return NewTemp;
            }
            else
            {
                //ShowMsgBLL.MsgDivBox1("不能上传" + extName + "文件,请上传:" + Passtr, "history.go(-1)");
                //这里改为自己的提示方式
                return "";
            }
        }
        /// 按比例缩小图片,自动计算高度 
        private void SmallPicHeight(Image objPic, string strNewPic, int i_w)
        {
            try
            {
                int i_h = (int)((float)objPic.Height * ((float)i_w / (float)objPic.Width));
                Bitmap bmp = new Bitmap(i_w, i_h);
                Graphics g = Graphics.FromImage(bmp);
                g.Clear(Color.White);
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.DrawImage(objPic, new Rectangle(0, 0, i_w, i_h), new Rectangle(0, 0, objPic.Width, objPic.Height), GraphicsUnit.Pixel);
                g.Dispose();
                objPic.Dispose();
                bmp.Save(strNewPic, ImageFormat.Jpeg);
                bmp.Dispose();
            }
            catch { }
            finally
            {
                objPic = null;
            }
        }
--------------------编程问答--------------------

        public static void CutForCustom(System.Drawing.Image initImage, string fileSaveUrl, int maxWidth, int maxHeight, int quality)
        {
            //原图宽高均小于模版,不作处理,直接保存
            if (initImage.Width <= maxWidth && initImage.Height <= maxHeight)
            {
                initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            else
            {
                //模版的宽高比例
                double templateRate = (double)maxWidth / maxHeight;
                //原图片的宽高比例
                double initRate = (double)initImage.Width / initImage.Height;

                //原图与模版比例相等,直接缩放
                if (templateRate == initRate)
                {
                    //按模版大小生成最终图片
                    System.Drawing.Image templateImage = new Bitmap(maxWidth, maxHeight);
                    Graphics templateG = Graphics.FromImage(templateImage);
                    templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                    templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    templateG.Clear(Color.White);
                    templateG.DrawImage(initImage, new Rectangle(0, 0, maxWidth, maxHeight), new Rectangle(0, 0, initImage.Width, initImage.Height), GraphicsUnit.Pixel);
                    templateImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                //原图与模版比例不等,裁剪后缩放
                else
                {
                    //裁剪对象
                    System.Drawing.Image pickedImage = null;
                    Graphics pickedG = null;

                    //定位
                    Rectangle fromR = new Rectangle(0, 0, 0, 0);//原图裁剪定位
                    Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位

                    //宽为标准进行裁剪
                    if (templateRate > initRate)
                    {
                        //裁剪对象实例化
                        pickedImage = new Bitmap(initImage.Width, (int)System.Math.Floor(initImage.Width / templateRate));
                        pickedG = Graphics.FromImage(pickedImage);

                        //裁剪源定位
                        fromR.X = 0;
                        fromR.Y = (int)System.Math.Floor((initImage.Height - initImage.Width / templateRate) / 2);
                        fromR.Width = initImage.Width;
                        fromR.Height = (int)System.Math.Floor(initImage.Width / templateRate);

                        //裁剪目标定位
                        toR.X = 0;
                        toR.Y = 0;
                        toR.Width = initImage.Width;
                        toR.Height = (int)System.Math.Floor(initImage.Width / templateRate);
                    }
                    //高为标准进行裁剪
                    else
                    {
                        pickedImage = new Bitmap((int)System.Math.Floor(initImage.Height * templateRate), initImage.Height);
                        pickedG = Graphics.FromImage(pickedImage);

                        fromR.X = (int)System.Math.Floor((initImage.Width - initImage.Height * templateRate) / 2);
                        fromR.Y = 0;
                        fromR.Width = (int)System.Math.Floor(initImage.Height * templateRate);
                        fromR.Height = initImage.Height;

                        toR.X = 0;
                        toR.Y = 0;
                        toR.Width = (int)System.Math.Floor(initImage.Height * templateRate);
                        toR.Height = initImage.Height;
                    }

                    //设置质量
                    //pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    //pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                    //裁剪
                    pickedG.DrawImage(initImage, toR, fromR, GraphicsUnit.Pixel);

                    //按模版大小生成最终图片
                    System.Drawing.Image templateImage = new Bitmap(maxWidth, maxHeight);
                    Graphics templateG = Graphics.FromImage(templateImage);
                    templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                    templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    templateG.Clear(Color.White);
                    templateG.DrawImage(pickedImage, new Rectangle(0, 0, maxWidth, maxHeight), new Rectangle(0, 0, pickedImage.Width, pickedImage.Height), GraphicsUnit.Pixel);

                    //关键质量控制
                    //获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
                    //ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
                    //ImageCodecInfo ici = null;
                    //foreach (ImageCodecInfo i in icis)
                    //{
                    //    if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif")
                    //    {
                    //        ici = i;
                    //    }
                    //}
                    //EncoderParameters ep = new EncoderParameters(1);
                    //ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);

                    //保存缩略图
                    //templateImage.Save(fileSaveUrl, ici, ep);
                    templateImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);

                    //释放资源
                    templateG.Dispose();
                    templateImage.Dispose();

                    pickedG.Dispose();
                    pickedImage.Dispose();
                }
            }

            //释放资源
            initImage.Dispose();
        }
--------------------编程问答--------------------

        //判断图片是否为CMYK格式图片.
        private bool IsCMYK(Image img)
        {
            bool isCmyk;
            if ((GetImageFlags(img).IndexOf("Ycck") > -1) || (GetImageFlags(img).IndexOf("Cmyk") > -1))
            { isCmyk = true; }
            else
            { isCmyk = false; }
            return isCmyk;
        }
        //图片像素数据的属性.
        private string GetImageFlags(Image img)
        {
            ImageFlags FlagVals = (ImageFlags)Enum.Parse(typeof(ImageFlags), img.Flags.ToString());
            return FlagVals.ToString();
        }
        //CMYK格式转化
        private Bitmap ConvertCMYK(Bitmap bmp)
        {
            Bitmap tmpBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(tmpBmp);
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            // 将CMYK图片重绘一遍,此时GDI+自动将CMYK格式转换为RGB了
            g.DrawImage(bmp, rect);
            Bitmap returnBmp = new Bitmap(tmpBmp);
            g.Dispose();
            tmpBmp.Dispose();
            bmp.Dispose();
            return returnBmp;
        }
        //构造随机文件名
        private string CreateFileName(string id)
        {
            char[] s = new char[]{'0','1', '2','3','4','5','6','7','8','9','A' ,'B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q' ,'R','S','T','U','V','W','X','Y','Z'};
            Random r = new Random();
            DateTime time = DateTime.Now;
            string name = id + "-"
                + time.Hour.ToString().PadLeft(2, '0')
                + s[r.Next(0, s.Length)].ToString()
                + time.Minute.ToString().PadLeft(2, '0')
                + s[r.Next(0, s.Length)].ToString()
                + time.Day.ToString().PadLeft(2, '0')
                + s[r.Next(0, s.Length)].ToString()
                + time.Second.ToString().PadLeft(2, '0')
                + s[r.Next(0, s.Length)].ToString();
            return name;
        }
        //删除文件,参数为相对路径
        public static bool DelFile(string filename)
        {
            string filepath = HttpContext.Current.Server.MapPath(filename);
            try
            {
                File.Delete(filepath);
                return true;
            }
            catch
            {
                return false;
            }
        }
        //创建目录,参数为物理路径
        public static void CreateForder(string directory)
        {
            try
            {
                if (!Directory.Exists(directory))
                    Directory.CreateDirectory(directory);
            }
            catch (Exception e)
            {
                throw (e);
            }
            finally { }
        }
        //删除目录,参数为相对路径
        public bool DeleteForder(string directory)
        {
            string filepath = HttpContext.Current.Server.MapPath(directory);
            if (System.IO.Directory.Exists(filepath))
            {
                System.IO.Directory.Delete(filepath, true);
                return true;
            }
            return false;
        }
    }
}

封装到BLL命名空间后,此处BLL可以是自己项目的命名空间名称。调用示例如下:

string imgurl = (new BLL.Upload()).UpImg(Imgurl.PostedFile, "/upload/", 120, 90, 3);
变量imgurl中即为返回的原图或裁剪后图片的地址如:2013408/P-14C46N25534U.jpg,在网站中使用此图片<img src="/upload/2013408/P-14C46N25534U.jpg">

如果同时需要大图和裁剪后的小图,则示例如下:
string smpic = string.Empty;//保存小图地址
string imgurl = (new BLL.Upload()).UpImg(Imgurl.PostedFile, "/upload/", 120, 90, 3,ref smpic);//保存大图地址



搞了这么多,累死了,一次还不让发太多,得分几部分发 --------------------编程问答-------------------- 太麻烦了那些企业网站的图片好像没经过裁切,是如何实现的呢 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 要么选择同样尺寸的图片上传,要么上传处理中进行裁剪缩放
上面贴出来的代码复制下来就可以直接用了,不知道所谓的麻烦在何处? --------------------编程问答-------------------- 我找到了 更简单的方法,先按规定的比例进行最大范围裁切,然后再进行缩放到固定大小 --------------------编程问答-------------------- 显示图的时候固定大小,当然上传图片必须规范 --------------------编程问答-------------------- --------------------编程问答-------------------- 如果按照你的想法,不可能有完美的解决办法。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,