美文网首页.NETdotNET计算机微刊
[解决方案] 自动调整图片

[解决方案] 自动调整图片

作者: gruan | 来源:发表于2017-09-14 18:03 被阅读0次
  • 项目源码
  • 原因: 图片尺寸/大小不一,没有规则,总共有300多G
  • 目标
    • 尽量不修改原有程序及架构, 以最小的代价使PC时代的图片库适应于移动端
    • 溯源 (要和源文件对应起来)
    • 可控 (预定义规则, 并不是随便进来一个请求都会得到处理)
    • 不处理第二次(如果已经处理过,直接输出, 否则处理并保存,以供下次请求直接使用)

ASP.NET 和 NETCore 的解决方法不同. 本文分两部份


ASP.NET

利用 VirtualFile / VirtualPathProviderStaticFileHandler 完成虚拟文件解析.

溯源

溯源的最简单办法是新文件源文件 名称,路径 保持一至. 而且有规则可以依, 就得把规则加到文件名中. 综合以上两点, 可以比较以下几种访问方式:

源: http://www.baidu.com/imgs/2017/09/09/abc.jpg

1. http://www.xxx.com/imgs/2017/09/09/abc.auto.s1.jpg
2. http://www.xxx.com/imgs/2017/09/09/abc.jpg?100x100
3. http://www.xxx.com/img?source=/imgs/2017/09/09/abc.jpg&w=100&h=100
  • 第1种在文件名和扩展名中间插入了占位符 auto 和 规则 s1. 拿到源文件地址后, 要处理成这种格式的, 不大方便 (仅此而已)
  • 第2种没有强插, 但是多了后缀. 这个的坏处就多了去,
    • 首先, 有问号和没有问号的都代表的是同一个文件,尤其是同时显示源图,和新图的时候, 问题更加突出.
    • Windows 下, 问号 (?) 是不能出现在文件名中的 (Linux 下没有测试,不知道). 这条是违背了第4条目标的.
  • 第3种就不多说了,太LOW了,不在考虑范围内.

综上所述, 我们这里选择第1种访问方式.
但是要使用这种方式, 就有点为难了, 因为: 没有入口 !

给个入口

静态类型的文件,ASP.NET 默认不会经过程序处理. 你可以在 GlobalBeginRequest 里设置一下断点,看能不能进来.
要想要程序可以处理静态文件,只需要在 web.config 里加入如下配置:

<system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <handlers>
    <!--设置可以由该程序处理的文件类型,必须-->
    <add name="jpg" path="*.jpg" verb="GET" type="System.Web.StaticFileHandler"/>
    <add name="gif" path="*.gif" verb="GET" type="System.Web.StaticFileHandler"/>
    <add name="png" path="*.png" verb="GET" type="System.Web.StaticFileHandler"/>
  </handlers>
</system.webServer>

至此, 你可以在 GlobalBeginRequest 里写处理程序了.

更进一层

VirtualPathProvider , VirtualFile 这两个东西的用处很多, 不了解的,可以自行搜索一下.
我了解的也不多, 只是在很久之前用它们取出 dll 中的母版页而已.这里我用它们来处理图片请求.

  • 首先, 在 GlobalApplication_Start 里注册 VirtualPathProvider:

    HostingEnvironment.RegisterVirtualPathProvider(new  VImgProvider(baseDir));
    

    VImgProvider 源码

  • 请求进入之后,首先会到 VImgProvider.FileExists 方法, 这里主要是判断进入的请求是不是可接受的图片类型, 目标文件是不是存在.

  • 然后进入 VImgFile.Open方法 源码

    1. 判断请求的文件是否存在, 如果存在,直接返回.
    2. 如果不存在, 判断进入的请求是否满足设定的规则.
    3. 如果满足规则, 从请求里拆分/解析/装配 源图片 的路径.
    4. 如果源图片 存在, 按规则对源图片进行缩放, 并将结果保存到同一目录下.
    5. 同样的请求第二次进来,只用走到第1步就可以返回了.

为了方便添加修改规则,我定义了一个热插拔的 JsonConfig. 只需要修改 Cfgs/SizeTypes.json 即可:
示例:

{
  "Types": [
    {
      "name": "s1",
      "width": 100,
      "height": 100,
      "quality": 70
    },
    {
      "name": "s2",
      "width": 200,
      "height": 200,
      "quality": 70
    },
    {
      "name": "s3",
      "width": 113,
      "height": 128
    }
  ]
}

当然, 以经生成的图片要手动删除, 才能应用新的配置


NETCore

通过修改 StaticFile 中间件的 FileProvider 来实现.

相对而言, NETCore 的实现要简单的多: 只需要修改 StaticFileMiddleware 的 FileProvider 即可.

var ap = new AutoImgFileProvider(this.Configuration);
//优先 WebRootFileProvider , 如果文件在它中能找得到,就不在去 AutoImageFileProvider 中在找一次了.
var cp = new CompositeFileProvider(env.WebRootFileProvider, ap);
var opt = new StaticFileOptions()
{
    FileProvider = cp
};

app.UseStaticFiles(opt);

需要添加 Nuget

  • Microsoft.Extensions.FileProviders.Composite
  • Microsoft.Extensions.FileProviders.Phyical

AutoImgFileProvider 是对 PhyicalFileProvider 做了一层包装, 而不是继承.
收到请求时 (GetFileInfo), 首先调用包装的 PhyicalFileProvider.GetFileInfo , 如果目标存在, 直接返回; 否则, 和ASP.NET的流程一样: 拆分/解析/组装/保存, 然后返回.

NETCore 规则配置采用了独立的配置文件, 修改规则,只需修改:
AutoImg.json 即可
示例:

{
  "AutoImg": {
    "BaseDir": "d:\\Imgs",
    "Types": [
      {
        "name": "s1",
        "width": 100,
        "height": 100
      },
      {
        "name": "s2",
        "width": 200,
        "height": 200
      },
      {
        "name": "s3",
        "width": 113,
        "height": 128
      }
    ]
  }
}

另附

NETCore 下图片处理采用 ImageSharp , NET FX 下用的是 ImageProcessor.
ImageSharp 不支持质量百分比.

相关文章

  • [解决方案] 自动调整图片

    项目源码 原因: 图片尺寸/大小不一,没有规则,总共有300多G 目标尽量不修改原有程序及架构, 以最小的代价使P...

  • fundamentals——亮度调整

    可以看见图片的通道 自动色调 自动对比度 自动颜色 调整 亮度对比度 静态 动态调整 静态:如上 动态:添加调整层...

  • 纯前端实现 JS本地预览图片

    前端JS上传图片,并预览图片,免后端 HTML JavaScript 样式问题自己调整即可,只是记录解决方案关于F...

  • webpack打包图片出现的图片路径问题

    webpack打包图片后,图片自动进入了dist文件夹内,但是图片地址还是根目录,导致图片一致显示不出。 解决方案...

  • jQuery的图片浏览插件Zoomimage

    插件描述:该jQuery插件能够让以当前流行的方式来展示图片。提供:预加载图片提示,对图片进行分组,自动调整图片显...

  • Mac 终端 命令 图片处理

    图片处理: 进入图片所在文件夹: 1.图片尺寸调整:高度60px,宽度自动 sips -Z 60 *.png 2....

  • ZGameEditor Visualizer

    本质图层自动化控制效果 步骤1添加图片添加图片 步骤2添加图片图层(多图层叠加)调用图片路径调整大小更改图片 步骤...

  • iOS11 HEIC图片上传到服务器自动旋转

    iOS11及以上 保存拍照的图片都会进行自动旋转处理,在上传图片时可通过图片格式判断获取图片类型,并重新调整方向,...

  • Axure笔记

    填入图片 1、拖拽部件库中的image到页面编辑框,填入图片时,显示“自动调整选框” 是:保持原图片大小 否:将图...

  • 拍摄图片自动旋转90度问题

    在做拍摄图片上传功能时发现图片如果大于2M就会出现自动旋转90度的问题, 在网上找到了解决方案, 给UIImage...

网友评论

    本文标题:[解决方案] 自动调整图片

    本文链接:https://www.haomeiwen.com/subject/piqdsxtx.html