每天解决一些c#小问题,在写微信小程序,或者一些手机软件接口,我们经常要用到上传图片到服务器,或者使用图床去保存我们的图片。

这次就简单明了的来梳理一下如何实现图片的接受和对接受到的图片进行一些处理。

一、实现图片的接收

1.首先要明确现在大部分前端的传输图片的统一规范都是通过POST请求+form表单提交文件的形式

通过 HttpContext.Current.Request.Files 获取请求头里面的文件

然后获取文件流,通过编译文件流另存为文件,保留到指定目录中

其中指定目录必须要现在系统中存在,不然会报错,这里通过前端传输suffix后缀的方式生成文件路径,可以自己写方法判断

上代码,这里是上传一张图片的示例,多张图片可自己更改添加遍历即可,我用的是时间戳命名

  1. [HttpPost,Route("UpLoadImageFiles")]
  2. public string UpLoadImageFiles(string suffix)//suffix是后缀的意思,可以自己判断,也可以前端传输
  3. {
  4. var files = HttpContext.Current.Request.Files;//首先先确定请求里夹带的文件数量
  5. if (files.AllKeys.Any())//如果存在文件
  6. {
  7. using (HttpClient client = new HttpClient())
  8. {
  9. HttpContextBase HttpContext = (HttpContextBase)Request.Properties["MS_HttpContext"];
  10. var text = HttpContext.Request.Files[0].InputStream;//获取到文件流
  11. string path = HttpContext.Request.MapPath("~/");//获取你的根目录
  12. string datetime = GetTimeStamp();
  13. string strPath = path + "File\\" + datetime + suffix;//这里要注意的是先要建立File文件夹,不然会报错,也可以自己写一个检测文件夹,这里就先不赘述
  14. StreamHelp.StreamToFile(text,strPath);//需要用到下一步的帮助类将其保存为文件
  15. //------------------以下是剪裁和压缩图片代码不需要的可以略过
  16. string imgPath = path + "File\\img\\" + datetime + suffix;
  17. ImageHelp img = new ImageHelp(strPath);
  18. img.GetReducedImage(0.8, imgPath);
  19. }
  20. return "添加成功";
  21. }
  22. return "无文件";
  23. }
  24. ///获取时间戳的方法
  25. private string GetTimeStamp()
  26. {
  27. TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
  28. return Convert.ToInt64(ts.TotalMilliseconds).ToString();
  29. }

2.获取到文件流后,需要一个帮助类将其转化为文件保存起来,我把它封装了一下StreamHelp.cs

  1. public static class StreamHelp
  2. {
  3. /// <summary>
  4. /// 流转文件
  5. /// </summary>
  6. /// <param name="stream"></param>
  7. /// <param name="fileName"></param>
  8. public static void StreamToFile(Stream stream, string fileName)
  9. {
  10. // 把 Stream 转换成 byte[]
  11. byte[] bytes = new byte[stream.Length];
  12. stream.Read(bytes, 0, bytes.Length);
  13. // 设置当前流的位置为流的开始
  14. stream.Seek(0, SeekOrigin.Begin);
  15. // 把 byte[] 写入文件
  16. FileStream fs = new FileStream(fileName, FileMode.Create);
  17. BinaryWriter bw = new BinaryWriter(fs);
  18. bw.Write(bytes);
  19. bw.Close();
  20. fs.Close();
  21. }
  22. /// <summary>
  23. /// 文件转流
  24. /// </summary>
  25. /// <param name="fileName"></param>
  26. /// <returns></returns>
  27. public static Stream FileToStream(string fileName)
  28. {
  29. // 打开文件
  30. FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
  31. // 读取文件的 byte[]
  32. byte[] bytes = new byte[fileStream.Length];
  33. fileStream.Read(bytes, 0, bytes.Length);
  34. fileStream.Close();
  35. // 把 byte[] 转换成 Stream
  36. Stream stream = new MemoryStream(bytes);
  37. return stream;
  38. }
  39. /// <summary>
  40. /// 流转Bytes
  41. /// </summary>
  42. /// <param name="stream"></param>
  43. /// <returns></returns>
  44. public static byte[] StreamToBytes(Stream stream)
  45. {
  46. byte[] bytes = new byte[stream.Length];
  47. stream.Read(bytes, 0, bytes.Length);
  48. // 设置当前流的位置为流的开始
  49. stream.Seek(0, SeekOrigin.Begin);
  50. return bytes;
  51. }
  52. /// <summary>
  53. /// Bytes转流
  54. /// </summary>
  55. /// <param name="bytes"></param>
  56. /// <returns></returns>
  57. public static Stream BytesToStream(byte[] bytes)
  58. {
  59. Stream stream = new MemoryStream(bytes);
  60. return stream;
  61. }
  62. }

二、图片的裁剪

接收图片的步奏这样就已经完成了,图片会保存到你自定义的文件夹中,接下来就是压缩图片

为了方便我将剪裁和压缩图片放在了同一个类中ImageHelp

首先是裁剪,我需要的是居中裁剪,也就是无论什么形状的图片传过来,都会裁剪成正方形

ImageTailor(string path)

剪裁使用的方法就是重画,使用Graphics.DrawImage(),新建一个正方形画布

首先先做长宽对比取最小的的边,然后把长的边剪裁,(bmp.Width - bmp.Height) / 2

这里通过改变原图的起始点进行检查,不用改变原图的长宽,防止图片形变。

GetReducedImage(double Percent, string targetFilePath)

然后通过百分比压缩图片,推荐80%就足够了。

  1. public class ImageHelp
  2. {
  3. public Image ResourceImage;
  4. private int ImageWidth;
  5. private int ImageHeight;
  6. public string ErrMessage;
  7. /// <summary>
  8. /// 类的构造函数
  9. /// </summary>
  10. /// <param name="ImageFileName">图片文件的全路径名称</param>
  11. public ImageHelp(string ImageFileName)
  12. {
  13. var BeImage = Image.FromFile(ImageFileName);
  14. ResourceImage = ImageTailor(ImageFileName);
  15. ErrMessage = "";
  16. }
  17. public bool ThumbnailCallback()
  18. {
  19. return false;
  20. }
  21. /// <summary>
  22. /// 裁剪居中
  23. /// </summary>
  24. /// <param name="path"></param>
  25. /// <returns></returns>
  26. public Image ImageTailor(string path)
  27. {
  28. Bitmap bmp = new Bitmap(path);
  29. var width = 0;
  30. var height = 0;
  31. var x = 0;
  32. var y = 0;
  33. if (bmp.Width > bmp.Height)
  34. {
  35. width = bmp.Height;
  36. height = bmp.Height;
  37. y = 0;
  38. x = (bmp.Width - bmp.Height) / 2;
  39. }
  40. else
  41. {
  42. width = bmp.Width;
  43. height = bmp.Width;
  44. y = (bmp.Height - bmp.Width) / 2;
  45. x = 0;
  46. }
  47. Bitmap newbm = new Bitmap(width, height);
  48. Graphics g = Graphics.FromImage(newbm);
  49. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  50. g.SmoothingMode = SmoothingMode.HighQuality;
  51. g.CompositingQuality = CompositingQuality.HighQuality;
  52. //前Rectangle代表画布大小,后Rectangle代表裁剪后右边留下的区域
  53. g.DrawImage(bmp, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
  54. g.Dispose();
  55. return newbm;
  56. }
  57. /// <summary>
  58. /// 生成缩略图重载方法1,返回缩略图的Image对象
  59. /// </summary>
  60. /// <param name="Width">缩略图的宽度</param>
  61. /// <param name="Height">缩略图的高度</param>
  62. /// <returns>缩略图的Image对象</returns>
  63. public Image GetReducedImage(int Width, int Height)
  64. {
  65. try
  66. {
  67. Image ReducedImage;
  68. Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
  69. ReducedImage = ResourceImage.GetThumbnailImage(Width, Height, callb, IntPtr.Zero);
  70. return ReducedImage;
  71. }
  72. catch (Exception e)
  73. {
  74. ErrMessage = e.Message;
  75. return null;
  76. }
  77. }
  78. /// <summary>
  79. /// 生成缩略图重载方法2,将缩略图文件保存到指定的路径
  80. /// </summary>
  81. /// <param name="Width">缩略图的宽度</param>
  82. /// <param name="Height">缩略图的高度</param>
  83. /// <param name="targetFilePath">缩略图保存的全文件名,(带路径),参数格式:D:Images ilename.jpg</param>
  84. /// <returns>成功返回true,否则返回false</returns>
  85. public bool GetReducedImage(int Width, int Height, string targetFilePath)
  86. {
  87. try
  88. {
  89. Image ReducedImage;
  90. Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
  91. ReducedImage = ResourceImage.GetThumbnailImage(Width, Height, callb, IntPtr.Zero);
  92. ReducedImage.Save(@targetFilePath, ImageFormat.Jpeg);
  93. ReducedImage.Dispose();
  94. return true;
  95. }
  96. catch (Exception e)
  97. {
  98. ErrMessage = e.Message;
  99. return false;
  100. }
  101. }
  102. /// <summary>
  103. /// 生成缩略图重载方法3,返回缩略图的Image对象
  104. /// </summary>
  105. /// <param name="Percent">缩略图的宽度百分比 如:需要百分之80,就填0.8</param>
  106. /// <returns>缩略图的Image对象</returns>
  107. public Image GetReducedImage(double Percent)
  108. {
  109. try
  110. {
  111. Image ReducedImage;
  112. Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
  113. ImageWidth = Convert.ToInt32(ResourceImage.Width * Percent);
  114. ImageHeight = Convert.ToInt32(ResourceImage.Height * Percent);
  115. ReducedImage = ResourceImage.GetThumbnailImage(ImageWidth, ImageHeight, callb, IntPtr.Zero);
  116. return ReducedImage;
  117. }
  118. catch (Exception e)
  119. {
  120. ErrMessage = e.Message;
  121. return null;
  122. }
  123. }
  124. /// <summary>
  125. /// 生成缩略图重载方法4,返回缩略图的Image对象
  126. /// </summary>
  127. /// <param name="Percent">缩略图的宽度百分比 如:需要百分之80,就填0.8</param>
  128. /// <param name="targetFilePath">缩略图保存的全文件名,(带路径),参数格式:D:Images ilename.jpg</param>
  129. /// <returns>成功返回true,否则返回false</returns>
  130. public bool GetReducedImage(double Percent, string targetFilePath)
  131. {
  132. try
  133. {
  134. Image ReducedImage;
  135. Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback);
  136. ImageWidth = Convert.ToInt32(ResourceImage.Width * Percent);
  137. ImageHeight = Convert.ToInt32(ResourceImage.Height * Percent);
  138. ReducedImage = ResourceImage.GetThumbnailImage(ImageWidth, ImageHeight, callb, IntPtr.Zero);
  139. ReducedImage.Save(@targetFilePath, ImageFormat.Jpeg);
  140. ReducedImage.Dispose();
  141. return true;
  142. }
  143. catch (Exception e)
  144. {
  145. ErrMessage = e.Message;
  146. return false;
  147. }
  148. }
  149. }

.net webapi 接收保存图片到服务器,并居中剪裁压缩图片的更多相关文章

  1. .net webapi 接收 xml 格式数据的三种情况

    webapi 接收 xml 的三种方法 前段时间接到一个任务写一个小接口,要接收java端返回过来的短信xml数据. 刚拿到项目,我的第一想法是对方会以什么形式发送xml格式的数据给我呢,设想三种情况 ...

  2. PHP批量保存图片到服务器再上传阿里云

    /* * 批量传输产品主图到阿里云 */ public function transferImage(){ $num = 50; $p = isset($this->request->ge ...

  3. CKEditor4.7怎样实现上传图片,浏览服务器(无需ckfinder),nodejs图片管理,字体居中,图片居中(超详细)

    首先是下载CKEditor,下载地址:http://ckeditor.com/download 选择里面的Customize自定义,如图 然后进入配置界面,第一个choose preset一般就选st ...

  4. .NET压缩图片保存 .NET CORE WebApi Post跨域提交 C# Debug和release判断用法 tofixed方法 四舍五入 (function($){})(jQuery); 使用VUE+iView+.Net Core上传图片

    .NET压缩图片保存   需求: 需要将用户后买的图片批量下载打包压缩,并且分不同的文件夹(因:购买了多个用户的图片情况) 文章中用到了一个第三方的类库,Nuget下载 SharpZipLib 目前用 ...

  5. ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结

    相册 iphone的相册包含摄像头胶卷+用户计算机同步的部分照片.用户可以通过UIImagePickerController类提供的交互对话框来从相册中选择图像.但是,注意:相册中的图片机器路径无法直 ...

  6. ios中摄像头/相册获取图片压缩图片上传服务器方法总结

    本文章介绍了关于ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结,有需要了解的同学可以参考一下下.     这几天在搞iphone上面一个应用的开发,里面有需要摄像头/相册编程和图片上传的问 ...

  7. Windows2003服务器IIS启用Gzip压缩的设置

    http://jingyan.baidu.com/article/148a192178ec834d71c3b12b.html     步骤 1 2 3 本文介绍的HTTP压缩方式,采用的是Window ...

  8. 微信小程序压缩图片并上传到服务器(拿去即用)

    这里注意一下,图片压缩后的宽度是画布宽度的一半 canvasToTempFilePath 创建画布的时候会有一定的时间延迟容易失败,这里加setTimeout来缓冲一下 这是单张图片压缩,多张的压缩暂 ...

  9. Ajax交互,浏览器接收不到服务器的Json数据(跨域问题)

    该问题的情景如下: 问题描述 Ajax的请求代码放在一台机器上,而服务器的java 路由程序放在另一个机子上,所以Ajax的url填写的是带"http://"  的地址,而不是相对 ...

随机推荐

  1. [LC] 231. Power of Two

    Given an integer, write a function to determine if it is a power of two. Example 1: Input: 1 Output: ...

  2. unittest(2)-加载用例的3种方式-输出测试报告

    # 导入测试类执行测试用例 import unittest from day_20191202.class_unittest import TestMathMethod, TestMulti # fr ...

  3. 前端自动化构建工具gulp

    1.gulp的安装 首先确保你已经正确安装了nodejs环境.然后以全局方式安装gulp: npm install -g gulp 全局安装gulp后,还需要在每个要使用gulp的项目中都单独安装一次 ...

  4. SpringMVC之添加照片并修改照片名字

    @RequestMapping(value="/addIdcardsSubmit",method={RequestMethod.POST,RequestMethod.GET}) p ...

  5. 瑞士一苹果店内iPhone突然爆炸致7人入院,iPhone还值得买吗?

    与国产手机高歌猛进态势呈现"最萌发展差"的,是以三星.苹果为代表的海外手机厂商在过去一年的疲态.数据显示,2017年小米手机产量较2016年增长幅度达76%,OPPO和vivo则分 ...

  6. LLDB奇巧淫技

    打印视图层级 这个相信很多人都会了,是ta是ta就是ta recursiveDescription 用法大概就是如下 123 po [self.view recursiveDescription] p ...

  7. gerrit Q&A

    One or more refs/for/ names blocks change upload 原因 这是错误的原因是底层的git仓库有一些不正确的引用,通常是有些开发者使用过程中,直接推送到git ...

  8. 千亿VR市场 将被国内厂商玩坏多少?

    将被国内厂商玩坏多少?" title="千亿VR市场 将被国内厂商玩坏多少?"> 智能硬件行业在不断寻求新的突破口,当智能手机.平板.电视.家电等都司空见惯之后,能 ...

  9. HF Java Chap 1

    介绍了java的工作方式以及几个有趣的小程序 Java的工作模式 大体来说有四个步骤: 源代码 编译器 编译器的输出 Java虚拟机 源代码 这是我们程序员接触到的部分.根据我们面临的问题,编写一个符 ...

  10. CoreGraphic

    public func UIGraphicsBeginImageContextWithOptions( size: CGSize, opaque: Bool, _ scale: CGFloat) si ...