《打造一个网站或者其他网络应用的文件管理接口(WebApi)第五章“服务器端分割压缩图片”》

========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41826865
========================================================

History

[WebApi] 捣鼓一个资源管理器--数据库辅助服务器文件访问

In This

在做网站开发时,我常常会做一些这样的工作:一张大图中包含了许多的小图,而网站中为了使用其中一张小图我不得不把大图切成一张张的小图。虽然这样的工作不多;但对于我来说在服务器端莫名的存储了一大堆小文件是很反感的事情;或许你会说使用css来完成大图中的小图显示;当然这是可以的。但是我假如需要下载该小图呢?这时无能为力了吧!

所以有了今天的服务器端剪切压缩图片的一章。

CodeTime

更改

本次版本相对上一张主要两个地方更改:新增 ImageUtils.cs,修改 ResourceApiController.cs

ImageUtils.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;namespace WebResource.Models
{public class ImageUtils{/// <summary>/// 图片类型对应的ImageFormat/// </summary>/// <param name="type">类型</param>/// <returns>ImageFormat</returns>public static ImageFormat GetFormat(string type){Dictionary<string, ImageFormat> types = new Dictionary<string, ImageFormat>();types.Add("bmp", ImageFormat.Bmp);types.Add("gif", ImageFormat.Gif);types.Add("ief", ImageFormat.Jpeg);types.Add("jpeg", ImageFormat.Jpeg);types.Add("jpg", ImageFormat.Jpeg);types.Add("jpe", ImageFormat.Jpeg);types.Add("png", ImageFormat.Png);types.Add("tiff", ImageFormat.Tiff);types.Add("tif", ImageFormat.Tiff);types.Add("djvu", ImageFormat.Bmp);types.Add("djv", ImageFormat.Bmp);types.Add("wbmp", ImageFormat.Bmp);types.Add("ras", ImageFormat.Bmp);types.Add("pnm", ImageFormat.Bmp);types.Add("pbm", ImageFormat.Bmp);types.Add("pgm", ImageFormat.Bmp);types.Add("ppm", ImageFormat.Bmp);types.Add("rgb", ImageFormat.Bmp);types.Add("xbm", ImageFormat.Bmp);types.Add("xpm", ImageFormat.Bmp);types.Add("xwd", ImageFormat.Bmp);types.Add("ico", ImageFormat.Icon);types.Add("wmf", ImageFormat.Emf);types.Add("exif", ImageFormat.Exif);types.Add("emf", ImageFormat.Emf);try{ImageFormat format = types[type];if (format != null)return format;}catch { }return ImageFormat.Bmp;}/// <summary>/// 图片转换为字节/// </summary>/// <param name="bitmap">图片</param>/// <param name="type">类型</param>/// <returns>字节码</returns>public static byte[] ToBytes(Bitmap bitmap, string type){using (MemoryStream stream = new MemoryStream()){bitmap.Save(stream, GetFormat(type));byte[] data = new byte[stream.Length];stream.Seek(0, SeekOrigin.Begin);stream.Read(data, 0, Convert.ToInt32(stream.Length));return data;}}/// <summary>  ///  调整图片宽度高度   /// </summary>  /// <param name="bmp">原始Bitmap </param>  /// <param name="newW">新的宽度</param>  /// <param name="newH">新的高度</param>  /// <returns>处理Bitmap</returns>  public static Bitmap Resize(Bitmap bmp, int newW, int newH){try{Bitmap b = new Bitmap(newW, newH);Graphics g = Graphics.FromImage(b);// 插值算法的质量   g.InterpolationMode = InterpolationMode.Default;g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);g.Dispose();return b;}catch{return null;}}/// <summary>/// 切片Bitmap:指定图片分割为 Row 行,Col 列,取第 N 个图片/// </summary>/// <param name="b">等待分割的图片</param>/// <param name="row">行</param>/// <param name="col">列</param>/// <param name="n">取第N个图片</param>/// <returns>切片后的Bitmap</returns>public static Bitmap Cut(Bitmap b, int row, int col, int n){int w = b.Width / col;int h = b.Height / row;n = n > (col * row) ? col * row : n;int x = (n - 1) % col;int y = (n - 1) / col;x = w * x;y = h * y;try{Bitmap bmpOut = new Bitmap(w, h, PixelFormat.Format24bppRgb);Graphics g = Graphics.FromImage(bmpOut);g.DrawImage(b, new Rectangle(0, 0, w, h), new Rectangle(x, y, w, h), GraphicsUnit.Pixel);g.Dispose();return bmpOut;}catch{return null;}}}
}

该类的 作用就是压缩和剪切图片,其具体实现也都注释清楚了; 如果不明白的地方,还望在评论中提出。

然后来看看这次的API更改。

ResourceApiController.cs
        /// <summary>/// Get Image/// </summary>/// <param name="name">MD5 Name</param>/// <returns>File</returns>[HttpGet][Route("{Id}/Img")]public async Task<HttpResponseMessage> GetImage(string Id, int w = 0, int h = 0, int r = 1, int c = 1, int n = 1){// Return 304var tag = Request.Headers.IfNoneMatch.FirstOrDefault();if (Request.Headers.IfModifiedSince.HasValue && tag != null && tag.Tag.Length > 0)return new HttpResponseMessage(HttpStatusCode.NotModified);// 判断参数是否正确if (w < 0 || h < 0 || r < 1 || c < 1 || n < 1)return new HttpResponseMessage(HttpStatusCode.BadRequest);// 默认参数情况直接返回if (w == 0 && h == 0 && r == 1 && c == 1 && n == 1)return await Get(Id);// 查找数据库Resource model = await db.Resources.FindAsync(Id);// 判断if (model == null || !GetContentType(model.Type).StartsWith("image"))return new HttpResponseMessage(HttpStatusCode.BadRequest);// 加载文件信息FileInfo info = new FileInfo(Path.Combine(ROOT_PATH, model.Folder, model.Id));if (!info.Exists)return new HttpResponseMessage(HttpStatusCode.BadRequest);// 打开图片Bitmap bitmap = new Bitmap(info.FullName);// 剪切if (r > 1 || c > 1){bitmap = ImageUtils.Cut(bitmap, r, c, n);}// 放大缩小if (w > 0 || h > 0){w = w == 0 ? bitmap.Width : w;h = h == 0 ? bitmap.Height : h;bitmap = ImageUtils.Resize(bitmap, w, h);}try{// Copy To Memory And Close.byte[] bytes = ImageUtils.ToBytes(bitmap, model.Type);// Get Tagstring eTag = string.Format("\"{0}\"", HashUtils.GetMD5Hash(bytes));// 构造返回HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);ContentDispositionHeaderValue disposition = new ContentDispositionHeaderValue(GetDisposition(model.Type));disposition.FileName = string.Format("{0}.{1}", model.Name, model.Type);disposition.Name = model.Name;// 这里写入大小为计算后的大小disposition.Size = bytes.Length;result.Content = new ByteArrayContent(bytes);result.Content.Headers.ContentType = new MediaTypeHeaderValue(GetContentType(model.Type));result.Content.Headers.ContentDisposition = disposition;// Set Cache 这个同Get方法result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now).AddHours(1);result.Content.Headers.LastModified = new DateTimeOffset(DateTime.Now);result.Headers.CacheControl = new CacheControlHeaderValue() { Public = true, MaxAge = TimeSpan.FromHours(1) };result.Headers.ETag = new EntityTagHeaderValue(eTag);return result;}catch { }finally{if (bitmap != null)bitmap.Dispose();}return new HttpResponseMessage(HttpStatusCode.BadRequest);}

由于代码量较多,我就不全部贴出来了;就把更改的地方写出来了;其中主要就是新增了一个 GetImage 方法。

在方法中,根据传入的参数我们进行一定的判断然后剪切压缩图片;最后打包为 Http 返回。

代码修改的地方就这么多。

RunTime

API


可以看见多API中多了一个接口;进入看看。


可以看见除了 Id 是必须,其他参数都是有默认值,可以不用传入。

  • Id:文件的MD5值,用于接口寻找对应文件
  • w:返回的图片宽度
  • h:返回的图片高度
  • r:row 行,代表横向分割为多少行;默认为1
  • c:column 列,代表纵向分割为多少列;默认为1
  • n:代表分割后取第N个图片
上传

惯例,首先上传一个图片。

访问

访问地址,可以使用原来的也可以使用新的地址,新的地址无非就是在后面加上“/img”

压缩

上面是改变宽度和高度后的结果;你可以右键保存图片看看图片是否是被改变了。

剪切

再来看看剪切的效果:

说说原理:

再来一张:

这样也就实现了,服务器端一张图片;客户端无数张图片;可以根据需求进行分割压缩;当然复杂一点你还可以加上一些特效;比如模糊;水印等等;这些服务端都可以做。

END

资源

[WebApi] 捣鼓一个资源管理器--服务器端分割压缩图片

下一章

下章准备把这些现有的功能进行组合,做一个管理界面;那样就可以在客户端管理服务端数据了;贼爽!

========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41826865
========================================================

[WebApi] 捣鼓一个资源管理器--服务器端分割压缩图片相关推荐

  1. Win10删除资源管理器左侧“视频、图片、音乐”等图标

    打开Win10系统的windows文件资源管理器,默认在左侧有:视频,图片,文档,下载,音乐等文件夹,很多朋友可能会觉的不使用就不要占地,比较强迫症,好了,没有问题,我们可以通过注册表来删除这些选项. ...

  2. 资源管理器添加漂亮的图片当背景

    想不想让你的资源管理器也像桌面一样可以自定义图片呢? 打开记事本编辑,复制一下源码粘贴: [ExtShellFolderViews] {BE098140-A513-11D0-A3A4-00C04FD7 ...

  3. 用不了tradingview?那自己捣鼓一个属于自己的量化分析平台

    现在很多国内用户用不了tradingview,原因很多,不赘述.其中一个原因是数据源使用了国外数据源.实际上,只要建立自己的实时行情数据库进行实时更新,加上自己做一个简单web服务,同时将所有日志.品 ...

  4. 捣鼓一个记账类的小程序

    项目前端小程序二维码: 简介: 记录个人,家庭等财务收支情况,可免费导出收支明细,与家人好友共享账本,让记账变得更简单 我的个人blog网站:https://www.zhooson.cn/ 里面其他全 ...

  5. 修改win7资源管理器默认启动位置

    打开资源管理器属性,在目标(T)后边加上: /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D} 俺滴笨笨原本目标(T)是: %windir%\explorer.ex ...

  6. Win10怎么重启资源管理器?重启资源管理器快捷键是什么

    在Windows系统中有一个资源管理器,其实它就是用来管理电脑里所有文件的,当用户想要进行某些操作时卡住无反应,很可能就是因为Windows资源管理器出问题了,下面我来给朋友们讲讲重启资源管理器的方法 ...

  7. 触摸键盘打开快捷方式_如何在Windows 10上使用键盘快捷方式打开文件资源管理器

    触摸键盘打开快捷方式 Windows 10 is packed with convenient keyboard shortcuts. One especially handy shortcut le ...

  8. Win10如何删除资源管理器中的图片/文档/音乐/视频等文件夹?

    Win10如何删除资源管理器中的图片/文档/音乐/视频等文件夹? 使用Win10系统的过程中,打开"此电脑",在资源管理器上面会有图片/文档/音乐/视频等6个文件夹,相信绝大数的用 ...

  9. 不务正业,捣鼓了一个破网站,全过程记录

    文章目录 为什么会有这个网站 预览几个页面 网站的缺陷 网站搭建过程 1. 服务器 2. 域名 3. html + js + css 4. 图片转换 5. 安装 web 服务器 6. 站点部署 小结 ...

  10. HashTab---Windows资源管理器的文件属性窗口中添加了一个叫做”文件校验”的标签...

    HashTab 是一个优秀的 Windows 外壳扩展程序,它在 Windows 资源管理器的文件属性窗口中添加了一个叫做"文件校验"的标签.该标签可以帮助你方便地计算文件的 MD ...

最新文章

  1. Spark streaming vs JStorm
  2. PCB 零件尺寸图:Arduino Mega 2560 尺寸
  3. LeetCode 705. Design HashSet (设计哈希集合)
  4. Spring源码学习的初步体会
  5. migrate和syncdb的区别(转载)
  6. c语言直流电机控制实验报告,直流电机实验报告.docx
  7. 80年代的海外经典动画片引进25周年纪念【转】
  8. /etc/shadow文件介绍
  9. Office365强制Microsoft Authenticator验证登录如何关闭
  10. 计算机如何连接iphone,iPhone6如何连接到电脑?iPhone6连接到电脑图解教程
  11. 弘辽科技:拼多多补访客资源是什么意思?提升多少个访客合适?
  12. MySQL —— 数据库基础
  13. [附源码]Python计算机毕业设计鞍山丘比特房屋租赁管理系统
  14. 小程序实现地图导航功能
  15. 网站显示 该内容被禁止访问 怎么解决
  16. Webots+ROS学习记录(4)——六轮全地形移动机器人
  17. QQ引流脚本,QQ扩列引流脚本实操演示
  18. HTTPS安全通讯 1. 密码学基础
  19. 什么是静态网站?什么是动态网站?
  20. 全力以赴提升粮食产能,建设责任担当

热门文章

  1. android studio for android learning (十八) android事件监听器绑定的方法详解
  2. android studio for android learning (十四) android的数据的存储sharedPreferences
  3. 计算机图形学完整笔记(六):三维图形变换
  4. java 男女 相邻交换 队形_(Java实现) 洛谷 P1091合唱队形
  5. Android TeaPickerView数据级联选择器
  6. jumserver 官方文档和
  7. 【校内模拟】2048
  8. netty使用(7)传输一个序列化对象
  9. 20170907wdVBA_ImportPicturesBaseOnExcel
  10. HTTP 长连接 使用场景