zoukankan      html  css  js  c++  java
  • app后端设计(12)--图片的处理

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



    app后端系列文章总目录

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

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

  • 相关阅读:
    利用pip批量升级packages
    基于cx_freeze编译PyQt4程序(numpy & scipy)
    利用Python读取Matlab的Mat文件内容
    在PyQt4中使用matplotlib
    个人Python常用Package及其安装
    python变量不能以数字打头
    Python Django开始
    Django 1.9 支持中文(转)
    Ubuntu1604中mysql的登录问题
    h3c防火墙的设置过程
  • 原文地址:https://www.cnblogs.com/cnsanshao/p/6111690.html
Copyright © 2011-2022 走看看