目录:

仿淘宝头像上传功能(一)——前端篇。

仿淘宝头像上传功能(二)——程序篇。

仿淘宝头像上传功能(三)——兼容 IE6 浏览器

源码下载:

仿淘宝头像上传并裁剪功能.zip

这里先定义了一个类,来专门处理图片的:

    public class ImageManager{}

以下是其中的方法:

        /// <summary>/// 获得文件名并去掉后缀。/// </summary>/// <param name="path">文件完所路径。</param>/// <returns>不带路径与后缀的文件名。</returns>private string GetFileName(string path){string fileName = Path.GetFileName(path);return fileName.Substring(0, fileName.Length - Path.GetExtension(fileName).Length);}

        /// <summary>/// 生成图片。/// </summary>/// <param name="image">要生成的图片对象。</param>/// <param name="savePath">保存位置。</param>/// <param name="high">是否设置绘制高质量。</param>private void SaveImage(Image image, string savePath, bool high){string fileExt = Path.GetExtension(savePath);ImageFormat imageFormat = ImageFormat.Jpeg;if (fileExt.Equals(".gif", StringComparison.OrdinalIgnoreCase)){imageFormat = ImageFormat.Gif;}if (fileExt.Equals(".png", StringComparison.OrdinalIgnoreCase)){imageFormat = ImageFormat.Png;}var directory = Directory.GetParent(savePath).FullName;if (!Directory.Exists(directory)){Directory.CreateDirectory(directory);}if (high){//以下代码为保存图片时,设置压缩质量。EncoderParameters encoderParams = new EncoderParameters();long[] quality = new long[1];quality[0] = 100;EncoderParameter encoderParam = new EncoderParameter(Encoder.Quality, quality);encoderParams.Param[0] = encoderParam;//获得包含有关内置图像编码解码器的信息的 ImageCodecInfo 对象。ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();ImageCodecInfo jpegICI = null;foreach (ImageCodecInfo imageCodecInfo in arrayICI){if (imageCodecInfo.FormatDescription.Equals("JPEG")){jpegICI = imageCodecInfo;//设置 JPEG 编码break;}}if (jpegICI != null){image.Save(savePath, jpegICI, encoderParams);}else{image.Save(savePath, imageFormat);}}else{//保存图片。
                image.Save(savePath, imageFormat);}}

        /// <summary>/// 获得重新绘制的缩略图对象。/// </summary>/// <param name="image">原图对象。</param>/// <param name="maxWidth">缩略图最大宽度。</param>/// <param name="maxHeight">缩略图最大高度。</param>/// <param name="high">是否设置绘制高质量。</param>/// <returns>绘制缩略图对象。</returns>private Bitmap GetThumbnailImage(Image image, int maxWidth, int maxHeight, bool high){//缩略图尺寸Size newSize = this.GetImageSize(new Size(image.Width, image.Height), new Size(maxWidth, maxHeight));//创建一张缩略图对象。var targetImage = new Bitmap(newSize.Width, newSize.Height);Graphics graphics = Graphics.FromImage(targetImage);if (high){graphics.CompositingQuality = CompositingQuality.HighQuality;graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;graphics.SmoothingMode = SmoothingMode.HighQuality;}//缩略图的矩形。var toRectangle = new Rectangle(0, 0, newSize.Width, newSize.Height);//缩略图在原图的位置的矩形。var fromRectangle = new Rectangle(0, 0, image.Width, image.Height);//将要原图绘制到 targetImage 对象里,该对象表示的是缩小后的图片。
            graphics.DrawImage(image, toRectangle, fromRectangle, GraphicsUnit.Pixel);graphics.Dispose();return targetImage;}

        /// <summary>/// 裁剪图片。/// </summary>/// <param name="sourceImage">原图对象。</param>/// <param name="cutRectangle">裁剪矩形信息。</param>/// <param name="high">是否设置绘制高质量。</param>/// <returns>裁剪后的图片对象。</returns>private Bitmap CutImage(Image sourceImage, Rectangle cutRectangle, bool high){//根据传入的裁剪坐标与宽高来裁剪出图片。var targetImage = new Bitmap(cutRectangle.Width, cutRectangle.Height);Graphics graphics = Graphics.FromImage(targetImage);if (high){graphics.CompositingQuality = CompositingQuality.HighQuality;graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;graphics.SmoothingMode = SmoothingMode.HighQuality;}//裁剪图片的矩形。var toRectangle = new Rectangle(0, 0, cutRectangle.Width, cutRectangle.Height);//裁剪图片在原图的位置的矩形。var fromRectangle = new Rectangle(cutRectangle.X, cutRectangle.Y, cutRectangle.Width, cutRectangle.Height);//将要裁剪的区域绘制到 image 对象里,该对象表示的是裁剪后的图片。
            graphics.DrawImage(sourceImage, toRectangle, cutRectangle, GraphicsUnit.Pixel);graphics.Dispose();return targetImage;}

        /// <summary>/// 获得裁剪正方形区域矩形。/// </summary>/// <remarks>/// 根据 cutRectangle 与原图显示区域的比例来计算出原图的裁剪区域范围矩形位置与大小。/// </remarks>/// <param name="width">原图宽度。</param>/// <param name="height">原图高度。</param>/// <param name="areaWidth">原图显示区域宽度。</param>/// <param name="areaHieght">原图显示区域高度。</param>/// <param name="cutRectangle">原图显示区域的裁剪区域范围矩形。</param>/// <returns>原图的裁剪区域范围矩形。</returns>private Rectangle GetCutRectangle(double width, double height, double areaWidth, double areaHieght, Rectangle cutRectangle){double w = 0.0;double h = 0.0;//计算出源图片缩小到显示区域范围内的宽度和高度。if (width < areaWidth && height < areaHieght){//没超出,不做计算。w = width;h = height;}else if ((width / height) > (areaWidth / areaHieght)){w = areaWidth;h = (w * height) / width;}else{h = areaHieght;w = (h * width) / height;}//计算出显示区域的图片的宽度与裁剪图片的宽度的比例。double widthScale = w / cutRectangle.Width;//计算出显示区域的图片的高度与裁剪图片的高度的比例。double heightScale = h / cutRectangle.Height;//计算出 X 坐标的比例(公式:显示区域宽度 / X 坐标)double smallWidthScale = w / cutRectangle.X;//计算出 Y 坐标的比例(公式:显示区域高度 / Y 坐标)double smallHeightScale = h / cutRectangle.Y;Rectangle resultRectangle = new Rectangle{//裁剪源图片的 X 坐标是:源图片宽度 / X 坐标比例。X = (int)(width / smallWidthScale),//裁剪源图片的 Y 坐标是:源图片高度 / Y 坐标比例。Y = (int)(height / smallHeightScale),//裁剪源图片的宽度是:源图片宽度 / 宽度比例。Width = (int)(width / widthScale),//裁剪源图片的高度是:源图片高度 / 高度比例。Height = (int)(height / heightScale)};return resultRectangle;}

        /// <summary>/// 获得指定图片尺寸的缩放尺寸。/// </summary>/// <param name="imageSize">原图尺寸。</param>/// <param name="maxSize">最大尺寸。</param>/// <returns>缩放后的尺寸。</returns>private Size GetImageSize(Size imageSize, Size maxSize){double w = 0.0;double h = 0.0;double sw = Convert.ToDouble(imageSize.Width);double sh = Convert.ToDouble(imageSize.Height);double mw = Convert.ToDouble(maxSize.Width);double mh = Convert.ToDouble(maxSize.Height);if (sw < mw && sh < mh){w = sw;h = sh;}else if ((sw / sh) > (mw / mh)){w = maxSize.Width;h = (w * sh) / sw;}else{h = maxSize.Height;w = (h * sw) / sh;}int width = Convert.ToInt32(w);int height = Convert.ToInt32(h);return new Size(width, height);}

        /// <summary>/// 裁剪并缩放正方形图片。/// </summary>/// <remarks>/// 1.先在原图上根据 x,y 坐标开始裁剪,裁剪的宽和高就是width,height。/// 2.在将裁剪出来后的图片,按照传入 side 缩略图尺寸来将裁剪出来的图片进行缩小或者放大。/// 3.保存图片。/// </remarks>/// <param name="sourcePath">原图位置(包含文件名)。</param>/// <param name="savePath">保存位置(目录)。</param>/// <param name="side">裁剪后的正方型缩略图尺寸。</param>/// <param name="high">是否设置绘制高质量。</param>/// <param name="cutImage">裁剪图片信息。</param>/// <param name="fileName">文件名(不带后缀)。</param>/// <param name="sizes">缩略图尺寸。</param>public void CutImage(string sourcePath, string savePath, int side, bool high, CutImageModel cutImage, string fileName, params int[] sizes){////判断原文件是否存在。//if(!File.Exists(sourcePath))//{//    throw new IOException(string.Format("路径:“{0}”文件不存在。", sourcePath));//}if(cutImage == null){throw new ArgumentNullException("cutImage", "cutImage 对象不可以是空的。");}if (cutImage.Width <= 0 || cutImage.Height <= 0){throw new TBGException("裁剪图片区域的宽度或者高度必须是大于 0 的。");}if (cutImage.AreaWidth <= 0 || cutImage.AreaHeight <= 0){throw new TBGException("原图预览区域的宽度或者高度必须是大于 0 的。");}using (Image sourceImage = Image.FromFile(sourcePath)){//计算并返回原图的裁剪区域范围矩形。var cutRectangle = this.GetCutRectangle(sourceImage.Width, sourceImage.Height, cutImage.AreaWidth, cutImage.AreaHeight, new Rectangle(cutImage.X, cutImage.Y, cutImage.Width, cutImage.Height));//裁剪原图。var targetImage = this.CutImage(sourceImage, cutRectangle, high);//按 side 尺寸缩放裁剪后的图片。var resultImage = this.GetThumbnailImage(targetImage, side, side, high);//获得原图扩展名。string fileExt = Path.GetExtension(sourcePath);//组合保存图片的路径。string saveImagePath = savePath.EndsWith("\\") ? savePath + fileName + "_" + side + fileExt : savePath + "\\" + fileName + "_" + side + fileExt;//保存图片(只支付 jpg, gif, png)。
                SaveImage(resultImage, saveImagePath, high);//生成缩略图if (sizes != null && sizes.Length > 0){foreach (int size in sizes){var thumbnailImage = this.GetThumbnailImage(resultImage, size, size, high);if (thumbnailImage != null){saveImagePath = savePath.EndsWith("\\") ? savePath + fileName + "_" + size + fileExt : savePath + "\\" + fileName + "_" + size + fileExt;SaveImage(thumbnailImage, saveImagePath, high);thumbnailImage.Dispose();}}}targetImage.Dispose();resultImage.Dispose();}////删除原图片。//File.Delete(sourcePath);}

        /// <summary>/// 上传并按比例缩放图片。/// </summary>/// <param name="uploadImage">图片上传信息。</param>/// <param name="newFileNameAction">生成新图片名称。</param>/// <param name="newFileName">带后缀新图片名称。</param>public ViewUploadImage LoadImage(UploadImage uploadImage, Func<string> newFileNameAction, out string newFileName){if (string.IsNullOrWhiteSpace(uploadImage.FileName)){throw new ArgumentNullException("fileName", "文件名不可以是空的。");}string fileExt = Path.GetExtension(uploadImage.FileName);if (string.IsNullOrWhiteSpace(fileExt)){throw new ArgumentNullException("fileExt", "文件名不可以没有后缀。");}newFileName = newFileNameAction() + fileExt.ToLower();string filePath = Path.Combine(uploadImage.SavePath, newFileName);if (!Directory.Exists(uploadImage.SavePath)){Directory.CreateDirectory(uploadImage.SavePath);}ViewUploadImage view = new ViewUploadImage();view.FileName = this.GetFileName(filePath);view.FileExt = fileExt;Image sourceImage = Image.FromStream(uploadImage.Stream);var targetImage = this.GetThumbnailImage(sourceImage, uploadImage.Width, uploadImage.Height, true);var size = this.GetImageSize(new Size(sourceImage.Width, sourceImage.Height), new Size(uploadImage.Width, uploadImage.Height));view.Width = sourceImage.Width;view.Height = sourceImage.Height;view.ViewWidth = size.Width;view.ViewHeight = size.Height;this.SaveImage(targetImage, filePath, true);sourceImage.Dispose();targetImage.Dispose();return view;}

    /// <summary>/// 裁剪图片模型信息。/// </summary>public class CutImageModel{/// <summary>/// 裁剪图片在原图里的左上角开始的 X 坐标。/// </summary>public int X { get; set; }/// <summary>/// 裁剪图片在原图里的左上角开始的 Y 坐标。/// </summary>public int Y { get; set; }/// <summary>/// 裁剪图片宽度。/// </summary>public int Width { get; set; }/// <summary>/// 裁剪图片高度。/// </summary>public int Height { get; set; }/// <summary>/// 加载区域的宽度。/// </summary>/// <remarks>/// 加载区域表示的是显示原图片的区域。/// 由于窗口中不可能显示完整某些图片,/// 所以大于这个区域的图片会先缩小到/// 不超出该区域的大小之后才显示出来。/// </remarks>public int AreaWidth { get; set; }/// <summary>/// 加载区域的高度。/// </summary>public int AreaHeight { get; set; }}

    /// <summary>/// 上传图片信息。/// </summary>public class UploadImage{/// <summary>/// 文件流。/// </summary>public Stream Stream { get; set; }/// <summary>/// 原图片名称。/// </summary>public string FileName { get; set; }/// <summary>/// 保存目录。/// </summary>public string SavePath { get; set; }/// <summary>/// 最大宽度。/// </summary>public int Width { get; set; }/// <summary>/// 最大高度。/// </summary>public int Height { get; set; }}

    /// <summary>/// 输出显示上传图片信息。/// </summary>public class ViewUploadImage{/// <summary>/// 文件名。/// </summary>public string FileName { get; set; }/// <summary>/// 扩展名。/// </summary>public string FileExt { get; set; }/// <summary>/// 原图片宽度。/// </summary>public int Width { get; set; }/// <summary>/// 原图片高度。/// </summary>public int Height { get; set; }/// <summary>/// 预览图片宽度。/// </summary>public int ViewWidth { get; set; }/// <summary>/// 预览图片高度。/// </summary>public int ViewHeight { get; set; }}

实际使用方法:

头像辅助类:

    /// <summary>/// 修改头像操作状态。/// </summary>public enum ChangeIconStatus{/// <summary>/// 成功。/// </summary>Success = 1,/// <summary>/// 失败。/// </summary>Error = 0,/// <summary>/// 登录失效。/// </summary>LoginInvalid = -1,/// <summary>/// 未上传头像。/// </summary>NotUpload = -2,}

这里是仿Discuz论坛的头像上传保存路径。

SiteFactory.Current.IconDefaultUrl

表示头像的访问地址。

    public class UserIconManager{private static readonly UserIconManager _current = new UserIconManager();public static UserIconManager Current{get{return _current;}}/// <summary>/// 获得用户头像。/// </summary>/// <param name="userId">用户编号。</param>/// <param name="fileName">头像名称(带后缀)。</param>/// <param name="size">头像尺寸。</param>/// <returns></returns>public string GetIcon(int userId, string fileName, IconSize size){string image = string.Empty;string icon = string.Empty;string uid = userId.ToString();int len = uid.Length;if (len < 11){for (int i = 0; i < 11 - len; i++){uid = "0" + uid;}}uid = uid.Substring(0, 3) + "/" + uid.Substring(3, 3) + "/" + uid.Substring(6, 3) + "/" + uid.Substring(9, 2);image = SiteFactory.Current.IconDefaultUrl.EndsWith("/") ? SiteFactory.Current.IconDefaultUrl + uid + "/" : SiteFactory.Current.IconDefaultUrl + "/" + uid + "/";string ext = Path.GetExtension(fileName);switch (size){case IconSize.Normal:icon = userId.ToString() + ext;break;case IconSize.Big:icon = userId.ToString() + "_" + ((int)IconSize.Big) + ext;break;case IconSize.Small:icon = userId.ToString() + "_" + ((int)IconSize.Small) + ext;break;default:icon = userId.ToString() + "_" + ((int)IconSize.Big) + ext;break;}return image + icon;}/// <summary>/// /// </summary>/// <param name="userId"></param>/// <returns></returns>public string GetSaveDirectory(int userId){string uid = userId.ToString();int len = uid.Length;if (len < 11){for (int i = 0; i < 11 - len; i++){uid = "0" + uid;}}uid = uid.Substring(0, 3) + "\\" + uid.Substring(3, 3) + "\\" + uid.Substring(6, 3) + "\\" + uid.Substring(9, 2);return SiteFactory.Current.SaveIconPath.EndsWith("\\") ? SiteFactory.Current.SaveIconPath + uid + "\\" : SiteFactory.Current.SaveIconPath + "\\" + uid + "\\";}}/// <summary>/// 输出显示上传头像信息。/// </summary>public class ViewIconImage{/// <summary>/// 文件名(带后缀)。/// </summary>public string FileName { get; set; }/// <summary>/// 原图片宽度。/// </summary>public int Width { get; set; }/// <summary>/// 原图片高度。/// </summary>public int Height { get; set; }/// <summary>/// 预览图片宽度。/// </summary>public int ViewWidth { get; set; }/// <summary>/// 预览图片高度。/// </summary>public int ViewHeight { get; set; }/// <summary>/// 原图头像地址。/// </summary>public string Image { get; set; }/// <summary>/// 小图片头像地址。/// </summary>public string SmallImage { get; set; }/// <summary>/// 大图片头像地址。/// </summary>public string BigImage { get; set; }}

    /// <summary>/// 头像大小。/// </summary>public enum IconSize{/// <summary>/// 通常。/// </summary>Normal = 0,/// <summary>/// 大图。/// </summary>Big = 110,/// <summary>/// 缩略图。/// </summary>Small = 37}

上传头像:

        /// <summary>/// 上传头像。/// </summary>/// <param name="userId">用户编号。</param>/// <param name="uploadImage">上传图片信息。</param>/// <returns></returns>public ViewIconImage UploadIcon(int userId, UploadImage uploadImage){string newFileName;var view = ImageManager.Current.LoadImage(uploadImage, () => UserIconManager.Current.GetSaveDirectory(userId) + userId, out newFileName);if (view == null){throw new Exception("头像上传失败。");}//保存头像后缀名。var result = this._userRepository.ChangeIcon(userId, view.FileExt);if (result){ViewIconImage iconImage = new ViewIconImage();iconImage.ViewWidth = view.ViewWidth;iconImage.ViewHeight = view.ViewHeight;iconImage.Image = UserIconManager.Current.GetIcon(userId, newFileName, IconSize.Normal);iconImage.BigImage = UserIconManager.Current.GetIcon(userId, newFileName, IconSize.Big);iconImage.SmallImage = UserIconManager.Current.GetIcon(userId, newFileName, IconSize.Small);return iconImage;}return null;}

修改头像:

        /// <summary>/// 修改头像。/// </summary>/// <param name="accountNumber">用户账号。</param>/// <param name="cutImage">裁剪图片输入信息。</param>public ChangeIconStatus ChangeIcon(string accountNumber, CutImageModel cutImage){var user = this.GetUser(accountNumber);if(user == null){return ChangeIconStatus.LoginInvalid;}string sourceImagePath = string.Empty;if (!string.IsNullOrWhiteSpace(user.Image)){string savePath = UserIconManager.Current.GetSaveDirectory(user.Id);sourceImagePath = savePath + user.Id.ToString() + user.Image;ImageManager.Current.CutImage(sourceImagePath, savePath, (int)IconSize.Big, true, cutImage, user.Id.ToString(), (int)IconSize.Small);return ChangeIconStatus.Success;}return ChangeIconStatus.NotUpload;}

转载于:https://www.cnblogs.com/cjnmy36723/p/3628474.html

仿淘宝头像上传功能(二)——程序篇相关推荐

  1. 最新仿淘宝B站购物直播小程序+带货完整PHP源码下载

    正文: 最新仿淘宝B站购物直播小程序+带货完整PHP源码下载,由于演示图太长了,所以我分别载图了两张,完整的演示图直接发压缩包了,有兴趣自行去查看. 当前版本已经修复直播间相关的一些BUG,还有商品新 ...

  2. java B2B2C 仿淘宝电子商城系统-Spring Cloud Feign的文件上传实现

    在Spring Cloud封装的Feign中并不直接支持传文件,但可以通过引入Feign的扩展包来实现,本文就来具体说说如何实现.需要JAVA Spring Cloud大型企业分布式微服务云构建的B2 ...

  3. 前端案例——2.仿淘宝关闭二维码案例

    <!-- 仿淘宝关闭二维码案例 --> <!-- 核心思路:利用样式的显示和隐藏完成,display:none隐藏元素:display:block显示元素. --> <! ...

  4. 仿淘宝 打开app时识别淘口令和解析保存到本地的带二维码图片的网址

    实现两个功能 1.仿淘宝淘口令  打开app时解析连接(如果复制得到的信息不是可直接使用的数据,那么还需要加一步拿到这些信息去后台获取具体信息,因为项目设计复制完就是一串地址,所以没做二次请求处理) ...

  5. js: 动画 筋斗云导航栏 仿淘宝关闭二维码

    筋斗云导航栏 <!DOCTYPE html> <html> <head lang="en"><meta charset="UTF ...

  6. Dom——仿淘宝关闭二维码

    仿淘宝关闭二维码 效果 整体的样式如上图所示.(素材图片可去淘宝保存图片) 当点击二维码广告旁边的叉叉,则会把广告关闭. 核心思路 点击叉叉,关闭整个广告,则需要的事件源有叉叉符号,整个广告盒子:事件 ...

  7. DOM ------ 仿淘宝关闭二维码

    仿淘宝关闭二维码 完成效果如下: //css代码.box{position: relative;width: 74px;height: 88px;border: 1px solid #ccc;marg ...

  8. 仿淘宝详情页 直接上代码

    仿淘宝详情页 直接上代码 package com.example.liketitledemo;import android.content.Context; import android.graphi ...

  9. 安卓项目实践——仿淘宝界面(二)——底部导航栏技术(Fragment实现)

    安卓项目实践--仿淘宝界面(一)--底部导航栏技术(Fragment实现) 1.实现效果展示 2.技术简述 该导航栏主要使用Fragment技术实现,关于Fragment的介绍大家可以自行百度,导航栏 ...

最新文章

  1. node.js(npm)|bower(bootstrap)|git
  2. Microsoft Azure云服务停机!系水泵未知原因关闭导致
  3. MySQL查询的进阶操作--分组查询
  4. 极速搭建一个个人博客网站
  5. 《死亡笔记》与绵球方块先生
  6. sql并发 锁 优化思路_并发优化–减少锁粒度
  7. python socket 大文件_python:socket传输大文件示例
  8. RedHat Enterprise Linux Server 5 在VMware Workstation 6.5的详细安装过程(2)
  9. mysql导入dat文件_mysql dat 导入数据库
  10. 吴恩达机器学习学习笔记第二章:单变量线性回归
  11. github操作实用命令
  12. hdu 3600 Simple Puzzle (判断N 数码是否有解)
  13. java微信公众号扫码登录对接流程
  14. 欧拉定理(Tetration,玲珑杯 Round#5 E lonlife 1060)
  15. 小福利,教大家用excel函数实现切片器的功能
  16. 服务产品化,或许是中国软件的出路
  17. 学海无涯!2021年抓住金三银四涨薪好时机,持续更新中
  18. Nutz cnd.wrap传参
  19. python的mag模块_Python Decimal max_mag()用法及代码示例
  20. 电脑硬盘为什么叫计算机,为什么女生的电脑总是很卡 原来硬盘是罪魁祸首

热门文章

  1. 作为Java程序员都应掌握:手把手教会你,含爱奇艺,小米,腾讯,阿里
  2. 2021/10/31 前端开发之JavaScript+jQuery入门 第十二章jQuery事件与动画
  3. i9 9980hk和i7 9750h那个好
  4. 重启 docker 服务、Docker 重启
  5. 内存条不会选?牌子太多眼花缭乱?实测告诉你内存条哪个牌子的质量好!
  6. 三星 s9 android 9,三星Galaxy S9系列的Android 9.0系统升级即将到来
  7. Bootstrap 模态框确定取消触发事件
  8. 带你了解抖音神器---Java实现图片(Image)转字符(ASCII)图片!
  9. python 设置 word中所有表格样式(行间距、缩进、字体、字号、颜色、磅值)
  10. css单线边框_HTML table表格边框设置为单线的方法