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

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

在app后端设计(1)—api(http://blog.csdn.net/newjueqi/article/details/14053733)这篇文章中,我提到过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图片裁剪的工具类,

[java] view plaincopy
  1. /**
  2. *
  3. */
  4. package com.bmob.worker.image;
  5. import java.awt.image.BufferedImage;
  6. import java.io.FileInputStream;
  7. import java.io.FileNotFoundException;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.util.concurrent.ExecutionException;
  11. /**
  12. */
  13. public class Image {
  14. /*
  15. 1、指定宽,高自适应,等比例缩放;
  16. 2、指定高, 宽自适应,等比例缩放;
  17. 3、指定最长边,短边自适应,等比例缩放;
  18. 4、指定最短边,长边自适应,等比例缩放;
  19. 5、指定最大宽高, 等比例缩放;
  20. 6、固定宽高, 居中裁剪)
  21. */
  22. public static int DefineWidth=1;
  23. public static int DefineHeight=2;
  24. public static int DefineLong=3;
  25. public static int DefineShort=4;
  26. public static int MaxWidthHeight=5;
  27. public static int DefineWidthHeight=6;
  28. /**
  29. * 图片缩放的方法
  30. *
  31. * @param mode
  32. 1、指定宽,高自适应,等比例缩放;
  33. 2、指定高, 宽自适应,等比例缩放;
  34. 3、指定最长边,短边自适应,等比例缩放;
  35. 4、指定最短边,长边自适应,等比例缩放;
  36. 5、指定最大宽高, 等比例缩放;
  37. 6、固定宽高, 居中裁剪)
  38. * @param src 源文件路径
  39. * @param desc 目标文件路径
  40. * @param width 指定宽
  41. * @param height 指定高
  42. * @param maxFrame 指定最长边
  43. * @param minFrame 指定最短边
  44. * @return
  45. * @throws Exception
  46. */
  47. public  String resize(int mode, String src,String desc, int width, int height, int maxFrame, int minFrame) throws Exception {
  48. String str="";
  49. BHPApplication.init();
  50. // create command
  51. ConvertCmd cmd = this.getCmd();
  52. IMOperation op =null;
  53. if( mode==Image.DefineWidth ){
  54. op=this.resizeDefineWidth( src,desc, width, height);
  55. }else if( mode==Image.DefineHeight ){
  56. op=this.resizeDefineHeight( src,desc, width, height);
  57. }else if( mode==Image.DefineLong ){
  58. op=this.resizeDefineLong( src,desc, maxFrame);
  59. }else if( mode==Image.DefineShort ){
  60. op=this.resizeDefineShort( src,desc, minFrame);
  61. }else if( mode==Image.MaxWidthHeight ){
  62. op=this.resizeMaxWidthHeight( src,desc, width, height);
  63. }else if( mode==Image.DefineWidthHeight ){
  64. op=this.resizeDefineWidthHeight( src,desc, width, height);
  65. }
  66. cmd.run(op);
  67. return str;
  68. }
  69. //指定宽,高自适应,等比例缩放;
  70. public  IMOperation resizeDefineWidth(String src,String desc, int width, int height){
  71. IMOperation op = new IMOperation();
  72. op.addImage(src);
  73. op.resize(width,null);
  74. op.addImage(desc);
  75. return op;
  76. }
  77. //指定高, 宽自适应,等比例缩放;
  78. public  IMOperation resizeDefineHeight(String src,String desc, int width, int height){
  79. IMOperation op = new IMOperation();
  80. op.addImage(src);
  81. op.resize(null,height);
  82. op.addImage(desc);
  83. return op;
  84. }
  85. //指定最长边,短边自适应,等比例缩放;
  86. public  IMOperation resizeDefineLong(String src,String desc, int maxFrame) throws Exception{
  87. InputStream is = new FileInputStream(src);//通过文件名称读取
  88. BufferedImage buff = ImageIO.read(is);
  89. int srcWidth=buff.getWidth();//得到图片的宽度
  90. int srcHeight=buff.getHeight();  //得到图片的高度
  91. is.close(); //关闭Stream
  92. IMOperation op = new IMOperation();
  93. op.addImage(src);
  94. if( srcWidth>srcHeight ){
  95. op.resize(maxFrame,null);
  96. }else{
  97. op.resize(null,maxFrame);
  98. }
  99. op.addImage(desc);
  100. return op;
  101. }
  102. //指定最短边,长边自适应,等比例缩放;
  103. public  IMOperation resizeDefineShort(String src,String desc, int minFrame) throws Exception {
  104. InputStream is = new FileInputStream(src);//通过文件名称读取
  105. BufferedImage buff = ImageIO.read(is);
  106. int srcWidth=buff.getWidth();//得到图片的宽度
  107. int srcHeight=buff.getHeight();  //得到图片的高度
  108. is.close(); //关闭Stream
  109. IMOperation op = new IMOperation();
  110. op.addImage(src);
  111. if( srcWidth<srcHeight ){
  112. op.resize(minFrame,null);
  113. }else{
  114. op.resize(null,minFrame);
  115. }
  116. op.addImage(desc);
  117. return op;
  118. }
  119. //指定最大宽高, 等比例缩放;
  120. public  IMOperation resizeMaxWidthHeight(String src,String desc, int width, int height){
  121. IMOperation op = new IMOperation();
  122. op.addImage(src);
  123. op.resize(width,height,'!');
  124. op.addImage(desc);
  125. return op;
  126. }
  127. //固定宽高, 居中裁剪
  128. public  IMOperation resizeDefineWidthHeight(String src,String desc, int width, int height){
  129. IMOperation op = new IMOperation();
  130. op.addImage(src);
  131. op.gravity("center").extent(width, height);
  132. op.addImage(desc);
  133. return op;
  134. }
  135. public  ConvertCmd getCmd(){
  136. ConvertCmd cmd = new ConvertCmd(true); //set true, use GraphicsMagick
  137. String path = "/usr/local/GraphicsMagick/bin"; //GraphicsMagick安装路径
  138. cmd.setSearchPath(path);
  139. return cmd;
  140. }
  141. }

app后端系列文章总目录

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

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

app后端设计(12)--图片的处理相关推荐

  1. app后端设计(php)

    来源:http://blog.csdn.net/column/details/mobilebackend.html?page=1 做了3年app相关的系统架构,api设计,先后在3个创业公司中工作,经 ...

  2. app后端设计(3)--短信,邮件,推送服务(2014.12.05更新)

    在app的后端设计中,免不了消息的推送,短信,邮件等服务,下面就个人的开发经验谈谈这方面. (1)最重要的是,各种推送一定要放在队列系统中处理,不然会严重影响api的响应时间. (2)短信方面 以前我 ...

  3. app后端设计(6)-- LBS

    在LBS的应用中,一个基本的需求是查找附近的用户,现在有两种做法: 1. 使用mysql的空间数据库,具体做法参考:http://blog.sina.com.cn/s/blog_a48af8c0010 ...

  4. APP后端数据接口注意事项

    2014年,移动APP的热度丝毫没有减退,并没有像桌面软件被WEB网站那样所取代,  不但如此,越来越多的传统应用.网站也都开始制作自己的移动APP,也就是我们常说的IOS客户端.android客户端 ...

  5. 产品原型设计5:移动App原型设计神器 - POP(Prototyping on Paper)

    一般来说,苦逼的互联网产品经理们都知道 Axure 这个原型设计工具,一方面是因为它提供了足够简单的拖拽操作,易上手,且有很多模板方便复用:另一方是因为它可直接输出html,直接在浏览器里给团队成员和 ...

  6. iOS设计 - 一款APP从设计稿到切图过程概述

    这篇文章站在GUI设计师的角度概述了APP从项目启动到切片输出的过程,相当于工作流程的介绍.这里写的不是一种规范,只是一种工作方法,加上技术的更新是非常快的,大家在具体工作中,一定要灵活运用. 这里我 ...

  7. Android App的设计架构:MVC,MVP,MVVM与架构经验谈

    本文转载自https://www.tianmaying.com/tutorial/AndroidMVC,原文作者周鸿博. 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开 ...

  8. [任务书+论文+PPT+源码]基于Android与多媒体的英文学习APP的设计与实现

    第1页 毕业设计(论文)题目:基于ANDROID与多媒体技术的英文学习APP的设计与实现设计(论文)要求及原始数据(资料):1.综述国内外移动互联现状及前景:2.了解ANDROID系统,理解ANDRO ...

  9. 毕业论文选题基于Web网站或Android APP的设计与实现

    一.基于Web的实验中心工作管理网站的设计与实现 二.基于Android的上课提醒APP的设计与实现 三.基于Android的健身管理APP的设计与实现 四.高校讲座信息APP的设计与实现 五.文本朗 ...

最新文章

  1. node.js 学习笔记三:路由url
  2. Google Chrome —— Windows 10 下谷歌浏览器所有页面崩溃(黑屏)问题解决方案
  3. Maven精选系列--标准目录结构
  4. jeecg公开培训课马上开始8点30
  5. 高等组合学笔记(二)二项式系数,差分方程与重集的排列组合
  6. 【R】ployroot函数求解多项式方程
  7. html——float与clear详解(深度好文)
  8. 解决引用flexible.js使第三方ui样式缩小的方法
  9. Ionic2学习笔记
  10. 基于FVC_MSAVI_EVI的荒漠化等级分类方法
  11. c语言程序设计基础课本答案,c语言程序设计基础课后习题参考 答 案与解析.doc...
  12. 函数式编程 freecodecamp
  13. Python 量化金融库最全汇总!
  14. Code Project精彩系列二
  15. 氨基苯酚/多巴胺仿生修饰碳纳米管/α-氧化铝/ CNTs-Ag纳米复合材料
  16. 谷歌地图高清卫星地图、电子地图和地形图有什么区别?
  17. 飞瞳引擎™AI集装箱识别检测云服务,全球两千企业用户投入使用,集装箱信息识别率99.98%以上高泛化性,集装箱信息识别云服务免费
  18. python使用163邮箱发送邮件
  19. Google Wave: There Will Be Backlash
  20. 番茄工作法-百度百科

热门文章

  1. 中断和异常,陷阱的区别和联系
  2. Codeforces Round #546 (Div. 2) B. Nastya Is Playing Computer Games
  3. Maven项目mybatis Invalid bound statement (not found)解决方法
  4. memcache 安装与简单使用
  5. C#获取枚举描述代码
  6. day-20: 安装软件包及rpm yum的介绍
  7. 前端学PHP之文件操作
  8. 图文教程:使用MyEclipse的hibernate工具从数据库反向生成实体Bean
  9. 【每日算法】C语言8大经典排序算法(2)
  10. 当思科交换机密码遗忘之后......(附图)