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

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

一、实现图片的接收

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

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

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

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

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

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

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

    public static class StreamHelp
{
/// <summary>
/// 流转文件
/// </summary>
/// <param name="stream"></param>
/// <param name="fileName"></param>
public static void StreamToFile(Stream stream, string fileName)
{
// 把 Stream 转换成 byte[]
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
stream.Seek(0, SeekOrigin.Begin);
// 把 byte[] 写入文件 FileStream fs = new FileStream(fileName, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(bytes);
bw.Close();
fs.Close();
} /// <summary>
/// 文件转流
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static Stream FileToStream(string fileName) { // 打开文件
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); // 读取文件的 byte[]
byte[] bytes = new byte[fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Close(); // 把 byte[] 转换成 Stream Stream stream = new MemoryStream(bytes);
return stream; } /// <summary>
/// 流转Bytes
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static byte[] StreamToBytes(Stream stream) { byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length); // 设置当前流的位置为流的开始 stream.Seek(0, SeekOrigin.Begin);
return bytes; } /// <summary>
/// Bytes转流
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static Stream BytesToStream(byte[] bytes)
{ Stream stream = new MemoryStream(bytes);
return stream;
}
}

二、图片的裁剪

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

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

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

ImageTailor(string path)

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

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

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

GetReducedImage(double Percent, string targetFilePath)

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

    public class ImageHelp
{
public Image ResourceImage;
private int ImageWidth;
private int ImageHeight;
public string ErrMessage; /// <summary>
/// 类的构造函数
/// </summary>
/// <param name="ImageFileName">图片文件的全路径名称</param>
public ImageHelp(string ImageFileName)
{
var BeImage = Image.FromFile(ImageFileName);
ResourceImage = ImageTailor(ImageFileName);
ErrMessage = "";
} public bool ThumbnailCallback()
{
return false;
} /// <summary>
/// 裁剪居中
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public Image ImageTailor(string path)
{
Bitmap bmp = new Bitmap(path);
var width = 0;
var height = 0;
var x = 0;
var y = 0;
if (bmp.Width > bmp.Height)
{
width = bmp.Height;
height = bmp.Height;
y = 0;
x = (bmp.Width - bmp.Height) / 2;
}
else
{
width = bmp.Width;
height = bmp.Width;
y = (bmp.Height - bmp.Width) / 2;
x = 0;
} Bitmap newbm = new Bitmap(width, height);
Graphics g = Graphics.FromImage(newbm);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
//前Rectangle代表画布大小,后Rectangle代表裁剪后右边留下的区域
g.DrawImage(bmp, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
g.Dispose();
return newbm;
} /// <summary>
/// 生成缩略图重载方法1,返回缩略图的Image对象
/// </summary>
/// <param name="Width">缩略图的宽度</param>
/// <param name="Height">缩略图的高度</param>
/// <returns>缩略图的Image对象</returns>
public Image GetReducedImage(int Width, int Height)
{
try
{
Image ReducedImage; Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback); ReducedImage = ResourceImage.GetThumbnailImage(Width, Height, callb, IntPtr.Zero); return ReducedImage;
}
catch (Exception e)
{
ErrMessage = e.Message;
return null;
}
} /// <summary>
/// 生成缩略图重载方法2,将缩略图文件保存到指定的路径
/// </summary>
/// <param name="Width">缩略图的宽度</param>
/// <param name="Height">缩略图的高度</param>
/// <param name="targetFilePath">缩略图保存的全文件名,(带路径),参数格式:D:Images ilename.jpg</param>
/// <returns>成功返回true,否则返回false</returns>
public bool GetReducedImage(int Width, int Height, string targetFilePath)
{
try
{
Image ReducedImage; Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback); ReducedImage = ResourceImage.GetThumbnailImage(Width, Height, callb, IntPtr.Zero);
ReducedImage.Save(@targetFilePath, ImageFormat.Jpeg); ReducedImage.Dispose(); return true;
}
catch (Exception e)
{
ErrMessage = e.Message;
return false;
}
} /// <summary>
/// 生成缩略图重载方法3,返回缩略图的Image对象
/// </summary>
/// <param name="Percent">缩略图的宽度百分比 如:需要百分之80,就填0.8</param>
/// <returns>缩略图的Image对象</returns>
public Image GetReducedImage(double Percent)
{
try
{
Image ReducedImage; Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback); ImageWidth = Convert.ToInt32(ResourceImage.Width * Percent);
ImageHeight = Convert.ToInt32(ResourceImage.Height * Percent); ReducedImage = ResourceImage.GetThumbnailImage(ImageWidth, ImageHeight, callb, IntPtr.Zero); return ReducedImage;
}
catch (Exception e)
{
ErrMessage = e.Message;
return null;
}
} /// <summary>
/// 生成缩略图重载方法4,返回缩略图的Image对象
/// </summary>
/// <param name="Percent">缩略图的宽度百分比 如:需要百分之80,就填0.8</param>
/// <param name="targetFilePath">缩略图保存的全文件名,(带路径),参数格式:D:Images ilename.jpg</param>
/// <returns>成功返回true,否则返回false</returns>
public bool GetReducedImage(double Percent, string targetFilePath)
{
try
{
Image ReducedImage; Image.GetThumbnailImageAbort callb = new Image.GetThumbnailImageAbort(ThumbnailCallback); ImageWidth = Convert.ToInt32(ResourceImage.Width * Percent);
ImageHeight = Convert.ToInt32(ResourceImage.Height * Percent); ReducedImage = ResourceImage.GetThumbnailImage(ImageWidth, ImageHeight, callb, IntPtr.Zero); ReducedImage.Save(@targetFilePath, ImageFormat.Jpeg); ReducedImage.Dispose(); return true;
}
catch (Exception e)
{
ErrMessage = e.Message;
return false;
}
}
}

最新文章

  1. 【Android】Android Studio 快速打开Github上的Demo
  2. MyEclipse之无法连接到MySQL数据库
  3. Ineedle驱动方式dpdk测试性能
  4. IE6 + png24 透明图片(滤镜)
  5. DuiLib——xml配置项
  6. UTF-8、GB2312都支持的汉字截取函数
  7. 【Chromium中文文档】沙箱FAQ
  8. android4.4组件分析--service组件-bindService源代码分析
  9. 20个很有用的CSS技巧
  10. spring6——AOP的编程术语
  11. Docker学习笔记1:CentOS7 下安装Docker
  12. Chipmunk僵尸物理对象的出现和解决(二)
  13. python 2.4 的字符串转时间(日期减法取间隔时间)
  14. pepperoni-app-kit
  15. java maven通过SMTP发送QQ邮件的完全步骤
  16. 性能监控(5)&ndash;JAVA下的jstat命令
  17. H 模拟水题
  18. 安装ubuntu的坑&amp;RHEL7配置
  19. Linux文件系统命令 umask
  20. html5 canvas贝塞尔曲线篇(上)

热门文章

  1. 吴裕雄--天生自然python学习笔记:Python3 输入和输出
  2. 读书笔记之 数字图像处理的MATLAB实现(第2版)
  3. Elegy written in a country church-yard
  4. 将js进行到底:node学习4
  5. mabatis中的元素属性
  6. 三星HTC价格跳水 安卓旗舰会否崩塌?
  7. 码海拾遗:Linux多线程mutex锁
  8. 本地开启https服务
  9. 《英诗金库》I-46:Full Fathom Five, by W. Shakespeare
  10. Yuur persistent XSS