博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
app后端设计(12)--图片的处理
阅读量:5292 次
发布时间:2019-06-14

本文共 4408 字,大约阅读时间需要 14 分钟。

app上线后,不断接受用户的反馈,于是,反馈非常差的情况下,都会有app的改版。

 

一旦app的改版,都会有比较大的UI改动,一改动UI,那么图片的尺寸也就必须要改变。

 

在app后端设计(1)—api()这篇文章中,我提到过app后台图片处理的一个基本原则,数据库中只保存原图的路径。对于同一张图片来说,针对不同机型,不同app版本所需要的不同尺寸,使用动态生成的策略,大体思路如下:

 

(1)      在图片的url末尾加上参数,声明需要生成的图片的新的尺寸,例如:户端需要图片(http://www.baidu.com/img/bdlogo.gif)的80*80的尺寸,则在图片的路径加上宽和高的参数(类似于CDN的机制) http://www.baidu.com/img/bdlogo.gif?w=80&h=80

(2)      服务器接收到图片的请求,先在缓存中查找这个尺寸的图片是否已经生成,如果已经在缓存中有记录,则不用重新生成。

(3)      如果该尺寸的图片还没生成,则生成新的图片尺寸,并把新生成的图片路径放在缓存中。

 

 

在app整个系统架构中,图片应该有两层缓存:

(1)      app本地的图片缓存,当app中没有该图片时,才去服务取

(2)      服务器的图片缓存,记录图片不同尺寸的保存路径

 

我的建议是,如果不差钱,直接使用七牛的云存储的服务吧,云存储不但可以加速图片的下载上传,也能实现图片的大量操作。要知道,速度才是用户体验最直接的部分。

 

如果真的要自己实现图片的裁切,那么要考虑到图片操作是非常消耗CPU,内存,和大量的磁盘IO,所以在选择图片处理工具要慎重!!!

 

推荐使用GraphicsMagick,一个久经考验的图片处理软件,支持多个平台,而且支持多种语言的客服端。GraphicsMagick是ImageMagick的一个分支,相对于ImageMagick而言,TA处理速度更快,消耗资源更少,并且大的图片处理网站,如 Flickr and Etsy  已经在使用TA了。

 

使用GraphicsMagick时,最折腾的是怎么配GraphicsMagick环境,查阅了大量的文章,都注明在linux下不能使用cmd.setSearchPath(path); ,但经过我实验,是可以的,而且配了这个的话,可以让linux和win下都运行同一段代码,只要把path放在配置文件中就好了。

 

下面我写的GraphicsMagick+Im4java图片裁剪的工具类,

/** *  */package com.bmob.worker.image;import java.awt.image.BufferedImage;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.util.concurrent.ExecutionException;/** */public class Image {	/*	 1、指定宽,高自适应,等比例缩放;	 2、指定高, 宽自适应,等比例缩放;	 3、指定最长边,短边自适应,等比例缩放;	 4、指定最短边,长边自适应,等比例缩放;	 5、指定最大宽高, 等比例缩放;	 6、固定宽高, 居中裁剪)	 */	public static int DefineWidth=1; 	public static int DefineHeight=2; 	public static int DefineLong=3; 	public static int DefineShort=4; 	public static int MaxWidthHeight=5; 	public static int DefineWidthHeight=6; 		/**	 * 图片缩放的方法	 * 	 * @param mode	 1、指定宽,高自适应,等比例缩放;	 2、指定高, 宽自适应,等比例缩放;	 3、指定最长边,短边自适应,等比例缩放;	 4、指定最短边,长边自适应,等比例缩放;	 5、指定最大宽高, 等比例缩放;	 6、固定宽高, 居中裁剪)	 * @param src 源文件路径	 * @param desc 目标文件路径	 * @param width 指定宽	 * @param height 指定高	 * @param maxFrame 指定最长边	 * @param minFrame 指定最短边	 * @return	 * @throws Exception	 */	public  String resize(int mode, String src,String desc, int width, int height, int maxFrame, int minFrame) throws Exception {				String str="";				BHPApplication.init();				// create command		ConvertCmd cmd = this.getCmd();		IMOperation op =null;		if( mode==Image.DefineWidth ){			op=this.resizeDefineWidth( src,desc, width, height);		}else if( mode==Image.DefineHeight ){			op=this.resizeDefineHeight( src,desc, width, height);		}else if( mode==Image.DefineLong ){			op=this.resizeDefineLong( src,desc, maxFrame);		}else if( mode==Image.DefineShort ){			op=this.resizeDefineShort( src,desc, minFrame);		}else if( mode==Image.MaxWidthHeight ){			op=this.resizeMaxWidthHeight( src,desc, width, height);		}else if( mode==Image.DefineWidthHeight ){			op=this.resizeDefineWidthHeight( src,desc, width, height);		}				cmd.run(op);				return str;	}		//指定宽,高自适应,等比例缩放;	public  IMOperation resizeDefineWidth(String src,String desc, int width, int height){		IMOperation op = new IMOperation();		op.addImage(src);		op.resize(width,null);		op.addImage(desc);				return op;	}		//指定高, 宽自适应,等比例缩放;	public  IMOperation resizeDefineHeight(String src,String desc, int width, int height){		IMOperation op = new IMOperation();		op.addImage(src);		op.resize(null,height);		op.addImage(desc);				return op;	}		//指定最长边,短边自适应,等比例缩放;	public  IMOperation resizeDefineLong(String src,String desc, int maxFrame) throws Exception{				InputStream is = new FileInputStream(src);//通过文件名称读取		BufferedImage buff = ImageIO.read(is);		int srcWidth=buff.getWidth();//得到图片的宽度		int srcHeight=buff.getHeight();  //得到图片的高度		is.close(); //关闭Stream				IMOperation op = new IMOperation();		op.addImage(src);		if( srcWidth>srcHeight ){			op.resize(maxFrame,null);		}else{			op.resize(null,maxFrame);		}				op.addImage(desc);				return op;	}		//指定最短边,长边自适应,等比例缩放;	public  IMOperation resizeDefineShort(String src,String desc, int minFrame) throws Exception {				InputStream is = new FileInputStream(src);//通过文件名称读取		BufferedImage buff = ImageIO.read(is);		int srcWidth=buff.getWidth();//得到图片的宽度		int srcHeight=buff.getHeight();  //得到图片的高度		is.close(); //关闭Stream						IMOperation op = new IMOperation();		op.addImage(src);		if( srcWidth

如果您觉得这系列的文章对你有所帮助,欢迎打赏。
支付宝账号:190678908@qq.com 收款人:曾健生

新建了“app后端技术” 交流qq群:254659220 

[文章作者]曾健生

[作者邮箱]h6k65@126.com

[作者QQ]190678908

[新浪微博] @newjueqi

[博客]http://blog.csdn.net/newjueqi

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/dingxiaoyue/p/4926761.html

你可能感兴趣的文章
[Flex] flex手机项目如何限制横竖屏?只允许横屏?
查看>>
tensorflow的graph和session
查看>>
6-1 并行程序模拟 uva210
查看>>
JavaScript动画打开半透明提示层
查看>>
Mybatis生成resulteMap时的注意事项
查看>>
jquery-jqzoom 插件 用例
查看>>
1007. Maximum Subsequence Sum (25)
查看>>
《算法》C++代码 快速排序
查看>>
iframe的父子层跨域 用了百度的postMessage()方法
查看>>
Js apply方法与call方法详解 附ES6新写法
查看>>
linux php全能环境一键安装,小白福利!
查看>>
Note(2): 一个JavaScript的贷款计算器
查看>>
js原型和原型链
查看>>
图片生成缩略图
查看>>
基于SQL调用Com组件来发送邮件
查看>>
关于Mysql select语句中拼接字符串的记录
查看>>
动态规划 例子与复杂度
查看>>
安装webpack-dev-server后,npm run dev报错
查看>>
[BZOJ4567][SCOI2016]背单词(Trie+贪心)
查看>>
git回退到某个版本并提交
查看>>