换个姿势访问图片

liuxx的个人博客 liuxx的个人博客     2022-08-18     364

关键词:

开篇先来聊一聊缩略图吧,其经典应用场景就是商品列表、详情以及查看大图时返回不同尺寸的图片。好处,额,闭上眼睛自己体会。我看到过一些做法是在图片保存时就生成三套缩略图提供给前端访问,这样其实是可以满足基本需求的,只是局限比较大,譬如下面这几种情况:
1、系统初期是基于pc做的开发,生成的缩略图也是提供给pc端使用。某个月黑风高的夜晚,领导突然拉着你的小手说我们明天开始做移动端,并且移动端的需要的图片尺寸和pc端不一样。
2、换领导了,新来的领导说列表页为什么加载这么慢,把宽320px的图片换成319px的,以前的数据全部要换~换~换~。
 
关于生成缩略图的思考
为了技(yi)术(lao)创(yong)新(yi),我们重新设计了缩略图的生成方式,与其生成固定不可更改的缩略图,不如根据前端的需(bian)求(hua)来生成缩略图,这样无论前端是需要什么尺寸我们都可以轻松应对。至于安全性,我们可以在后端配置允许访问的尺寸集合,遇到非法的请求,直接给他一张小黄图就好。于是我们的图片访问流程大概变成了这个样子:
1、用户发起图片请求,服务端拿到请求,检查图片是否存在,不存在则返回小黄图。
2、验证图片请求是否带有尺寸参数,没有则返回原图,尺寸超过原图也直接返回原图。
3、如果带有尺寸参数,验证是否在服务器允许的参数范围内,不在则返回小黄图。
4、判断该尺寸的缩略图是否存在,不存在则生成缩略图,存在即直接返回缩略图。
 
缩略图只会在第一次访问时生成,总体来说不会太影响图片访问速度。思路大概就是这个样子,接下来就只需要从服务端拿到用户的图片请求并处理。
 
关于图片请求url的思考
平时我们访问图片的方式大概是这个样子,http://xx.com/xx.png,那么带参数的图片请求会是个什么样子呢,我想最好像这样吧:http://xx.com/xx.png?width=320。
 
后端如何拿到这个请求的参数并控制其返回的内容。我能想到的有两个办法:
1、将图片访问集中到一个webapi接口,将图片路径和尺寸当做参数传过来统一处理,webapi接口以流的形式返回图片。
2、是否可以将特定的图片请求使用一个自定义的IHttpHandler来处理。
 
其实仔细一想,第一个办法实现起来并不是那么优雅,并且也不能达到我们http://xx.com/xx.png?width=320的需求,甚至图片返回的速度也会变慢不少,那么我们来分析第二个办法的可行性。我的图片都是存储在/upload/image/这个目录之下,那么前端的图片访问也必然是http://file.com/upload/image/xx.png,我们只需要将带/upload/image/的请求映射到我们自定义的IHttpHandler来处理即可。
 
解决方案
1、自定义HttpHandler:
 
using System.Drawing;
using System.Web;
using cczcrv.Web.File.Uploader.Image;
using System.IO;

namespace cczcrv.Web.File.Filters
{
    public class GetImageHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            //图片不存在,返回默认图片
            var path = context.Server.MapPath(context.Request.Url.AbsolutePath);
            if (!System.IO.File.Exists(path))
            {
                CreateImageResponse(context, "");
                return;
            }

            int width = 0;
            var strWidth = context.Request.Params["width"];
            if (!string.IsNullOrWhiteSpace(strWidth) && int.TryParse(strWidth, out width))
            {
                var index = path.LastIndexOf(\);

                //缩略图目录不存在,创建目录
                var thumbnailDirectory = $"{path.Substring(0, index)}/thumb_{width}";
                if (!Directory.Exists(thumbnailDirectory))
                {
                    Directory.CreateDirectory(thumbnailDirectory);
                }
                var thumbnailPath = $"{thumbnailDirectory}/{path.Substring(index + 1)}";
                //缩略图不存在,生成缩略图
                if (!System.IO.File.Exists(thumbnailPath))
                {
                    var image = Image.FromFile(path);

                    //width大于图片本身宽度,则返回原图
                    if (width >= image.Width)
                    {
                        CreateImageResponse(context, path);
                        return;
                    }
                    ThumbnailHelper.MakeThumbnail(image, thumbnailPath, width, 100, ThumbnailModel.W);
                }
                CreateImageResponse(context, thumbnailPath);
                return;
            }
            CreateImageResponse(context, path);
        }

        public bool IsReusable { get { return false; } }

        #region 私有方法

        /// <summary>
        /// 返回图片
        /// </summary>
        /// <param name="context">当前上下文</param>
        /// <param name="filePath">图片路径</param>
        private void CreateImageResponse(HttpContext context, string filePath)
        {
            context.Response.ContentType = "image/JPEG";
            context.Response.WriteFile(filePath);
            context.Response.End();
        }

        #endregion

    }
}

 

 
2、在webconfig中添加handler处理配置:
<add name="getImage" path="/upload/image/*" verb="GET" type="cczcrv.Web.File.Filters.GetImageHandler" />

运行效果可以通过下面两个链接查看:

原图:http://file.cczcrv.com/upload/image/201612/15/w_1903359727.png

缩略图:http://file.cczcrv.com/upload/image/201612/15/w_1903359727.png?width=100

 

这个Handler中还可以做很多事情,比如图片防盗链,ip黑名单等等,不过说到底原理只是一个IHttpHandler的应用而已。

 

换个姿势为安装包重签名

一直在关注这个Robotium开源框架,兴起开始耍起来,关于这个重签名,命令行我只说这个的,有的博主,我不得不再次吐槽,你自己试验了么?现将个人实际操作总结如下:step:1、去除签名将apk文件后缀改为.zip,然后从winrar中删... 查看详情

换个姿势,十分钟拿下java/kotlin泛型(代码片段)

0x1、引言解完BUG,又有时间摸鱼学点东西了,最近在复习Kotlin,跟着朱涛的《Kotlin编程第一课》查缺补漏。看到泛型这一章时,想起之前面一家小公司时的面试题:说下你对泛型协变和逆变的理解?读者可... 查看详情

淘宝关键词提取:换个姿势看同行都在用的高流量高搜索热词

同行的卖家哪些词用的多,往往这些词搜索量也大。有些我们想不出来的词,其他卖家想到了,那么就可以通过提取,列出来供我们自己使用。 举个粟子,我们准备上架一款打底裤产品,需要一些相关的买家搜索量大、点选... 查看详情

vue项目静态资源(图片,字体)引用路径正确姿势

参考技术A首先,vue项目有两个地方可以存放静态资源。一个是assets文件夹,一个是static文件夹(地址栏输入static可以直接访问)。放到static里面webpack打包后只会把资源复制到发布目录而不会把小图片优化为base64。而assets内的资... 查看详情

原创多dpi适配的新姿势

多dpi适配的新姿势简介Android中经常要通过ImageView进行图片资源显示。在加载图片时,首先要考虑的两个因素就是体验问题和性能问题。其中,体验问题是指图片显示的是否正确(例如Universal-Image-Loader在适配Adapter图片资源时会导... 查看详情

springboot进阶

表单验证 AOP处理请求AOP是一种编程范式。与语言无关,是一种程序设计思想。面向过程到面向对象。换个角度看世界,换个姿势处理问题。 统一异常处理 单元测试 查看详情

访问天地图wmts服务的正确姿势

天地图2018版对天地图应用开发流程进行了升级改造,主要有两点变化:(1)接口升级为tianditu.gov.cn政府域名,支持HTTP/HTTPS协议,原有服务域名tianditu.com继续保留;(2)自2019年1月1日起,天地图API及服务接口调用都需要获取开... 查看详情

httpcontext访问的正确姿势(代码片段)

本文章转发自:https://www.cnblogs.com/tianqing/p/12570801.html使用HttpContext的具体场景:1.在Controller层访问HttpContext2.在中间件中使用HttpContext3.在数据访问层使用HttpContext4.在后台线程中访问HttpContext5.在Razor页面模型中访问HttpContext6.在Razor... 查看详情

springboot实现多图片上传并回显,涨姿势了~(代码片段)

作者:不学无数的程序员链接:https://www.jianshu.com/p/3e28b94444be这两天公司有需求让做一个商户注册的后台功能,其中需要商户上传多张图片并回显。由于之前没做过这方面的东西,此篇文章用以记录一些知识点ÿ... 查看详情

springboot实现多图片上传并回显,涨姿势了~(代码片段)

点击关注公众号,Java干货及时送达作者:不学无数的程序员链接:https://www.jianshu.com/p/3e28b94444be这两天公司有需求让做一个商户注册的后台功能,其中需要商户上传多张图片并回显。由于之前没做过这方面的东西&... 查看详情

opencv实践之路——使用imread()函数读取图片的六种正确姿势(代码片段)

本文由@星沉阁冰不语出品,转载请注明作者和出处。文章链接:http://blog.csdn.net/xingchenbingbuyu/article/details/51375078微博:http://weibo.com/xingchenbing 经常看到有人在网上询问关于imread()函数读取图片失败的问题。今天心... 查看详情

一个非常详细测试上传的姿势

【情况】上传点界面:这个上传点只有一个界面,且上传后会自动删除。成功突破会返回一串秘钥。上传点抓包界面如下:上传一个普通图片,返回路径upload/20160226222154_920.jpg可以看到,整个上传包没有任何多余的参数。除了文... 查看详情

ios监听scrollview/tableview滚动的正确姿势

主要介绍监测tableView垂直滚动的舒畅姿势监测scrollView/collectionView横向滚动的正确姿势1.监测tableView垂直滚动的舒畅姿势通常我们用KVO或者在scrollViewDidScroll代理方法中监听ScrollView/TableView的contentOffset,比如监听TableView的contentOffset... 查看详情

springboot中aop的使用

...cedureOrientedProgramming 再谈AOP1、面向过程到面向对象2、换个角度看世界,换个姿势处理问题 3、 查看详情

涨姿势了,殊途同归的图片交互动效制作!(代码片段)

最近,在CodePen上,看到一个非常有意思的图片动效,效果如下:原效果链接:CodePenDemo-1divpureCSSblindsstaggeredanimationin13declarations本身这个动画效果,并没有多惊艳。惊艳的地方在于原作者的实现方式非常有趣,我们简单来看看:&l... 查看详情

浅析hiveudaf的正确编写方式-论姿势的重要性-系列四-如何直接访问metastoreservice(附源码)

前言大家好,我是明哥。HIVE作为大数据生态的数仓解决方案,因为历史的原因在很多行业很多公司都有着广泛的应用。对于比较复杂的业务逻辑,HIVESQL往往比较难以表达,此时大家在开发中往往会辅以HIVEUDF。所... 查看详情

该如何以正确的姿势插入svgsprites?(代码片段)

前言  大家好,这里是@IT·平头哥联盟,我是首席填坑官——苏南(South·Su),今天要给大家分享的是SVGSprites(也叫雪碧图),所谓雪碧图,当然就不是我们常喝的雪碧饮料(Sprites)哦,哈哈~  当下流程的移动端,手机型号太... 查看详情

springcloudfeign的两种使用姿势

...散,本文就来集中记录一下声明式客户端Feign的一些使用姿势。三个步骤即可搞定:创建一个名为eureka_server的SpringBoot工程,并在pom.xml中添加好对应依赖修改应用主类,添加@EnableEurekaServer注解配置application.properties文件如下所示... 查看详情