文件上传+截图+预览升级版-我们到底能走多远系列(23)

我们到底能走多远系列(23)

扯淡:新的一年开始啦,各位有志青年也该发力学习,工作,赚钱啦!

  来个笑话:劫匪进某银行抢劫:钱是国家的,命是自己的!通通不许动!” 于是没有一个人动。抢劫成功。

  一个新来硕士劫匪问老大:我们赶快数一下抢了多少吧。老劫匪说,你傻啊?这么多数到什么时候啊?今天晚上看新闻不就知道了吗?(各位这就是工作经验啊)

  第二天劫匪们看新闻:4名劫匪,劫去某银行,1个亿...

  老大开骂了:不对啊,昨天数了3边就1千万呀,马德~,这么幸苦,人家动一下嘴皮子就赚了我们9倍。再也不干抢银行了~(这就是程序员啊)

  

主题:

1,截图改进

年前写的,上传图片,截图:抓我  供大家参考,上次的流程是这样的,上传图片到后台,保存到文件夹,然后页面上把原尺寸的图片展现出来,进行截图,截图成功后把截图坐标尺寸返回后台,后台根据这些参数把后台的图片剪切,然后把截图的效果展现在页面。

那么这儿就有个问题啦:

就是把原图展现在页面上进行截图的时候,如果上传的图片很大,会导致页面展现很难看!

参考了博客园的头像截图,只有通过缩小原图的方式来实现,又考虑到我做的不是截什么头像这样的小图,我是要一张高分辨率的图片,如此就有了一下方案:

把原图上传后,进行等比例缩放,缩放到页面上展现框中能够展现的大小,把原图存服务器,缩放图展现在截图页面,把缩放的比例,传到页面。

然后进行截图,截图完毕后,回传坐标,在js里结合坐标和缩放比例算出实际图中截图的坐标,然后交给后台去裁剪后台的原图,这样剪切出来的图片分辨率不会失真了。

 

事实上,明白了整个流程,根据上次的文章,就能写出来了,所以这里就不贴很多代码了

首先截图插件使用imgAreaSelect

            piso = $('#photo').imgAreaSelect({ 
                  x1: 0, y1: 0, x2: 72, y2: 128,
                  aspectRatio: '9:16' ,onSelectEnd: preview,
                persistent : true,
                instance: true,
                enable:true,
                handles: true
            });

返回截图坐标的时候,用js还原成原图上的坐标:

    list[0] = parseInt($("#x1").val()/sx);
    list[1] = parseInt($("#x2").val()/sx);
    list[2] = parseInt($("#y1").val()/sy);
    list[3] = parseInt($("#y2").val()/sy);
    list[4] = parseInt($("#w").val()/sx);
    list[5] = parseInt($("#h").val()/sy);

等比例缩放:

    
    public static double[] saveThumbnailImage(InputStream is, String imgType, File saveFile, int width, 
            int height,boolean equalProportion) throws IOException{
        BufferedImage srcImage;
        if(imgType ==null || "".equals(imgType)){
            imgType = "JPEG";
        }
        srcImage=ImageIO.read(is);
        ImageResizeModel imageResizeModel = new ImageResizeModel();
        imageResizeModel.setBuffedImage(srcImage);
        imageResizeModel.setSx(imageResizeModel.getSx());
        imageResizeModel.setSy(imageResizeModel.getSy());
        if(width>0||height>0){
            ImageResizeModel imageResizeModel1 = resize(srcImage,width,height,equalProportion);
            imageResizeModel.setBuffedImage(imageResizeModel1.getBuffedImage());
            imageResizeModel.setSx(imageResizeModel1.getSx());
            imageResizeModel.setSy(imageResizeModel1.getSy());
        }
        ImageIO.write(imageResizeModel.getBuffedImage(),imgType,saveFile);
        
        double[] ratio = new double[]{imageResizeModel.getSx(), imageResizeModel.getSy()};
        return  ratio; 
    }
    
    /** 
     * 将原图片的BufferedImage对象生成缩略图 
     * source:原图片的BufferedImage对象 
     * targetW:缩略图的宽 
     * targetH:缩略图的高 
     */
    public static ImageResizeModel resize(BufferedImage source,int targetW,int targetH,boolean equalProportion){  
        int type=source.getType();  
        BufferedImage target=null;  
        double sx=(double)targetW/source.getWidth();  
        double sy=(double)targetH/source.getHeight();
        //这里想实现在targetW,targetH范围内实现等比例的缩放  
          //如果不需要等比例的缩放则下面的if else语句注释调即可  
        if(equalProportion){  
            if(sx>sy){
                sx=sy;  
                targetW=(int)(sx*source.getWidth());  
            }else{
                sy=sx;  
                targetH=(int)(sx*source.getHeight());  
            }  
        }  
        if(type==BufferedImage.TYPE_CUSTOM){
            ColorModel cm=source.getColorModel();  
            WritableRaster raster=cm.createCompatibleWritableRaster(targetW,targetH);  
            boolean alphaPremultiplied=cm.isAlphaPremultiplied();  
            target=new BufferedImage(cm,raster,alphaPremultiplied,null);  
        }else{  
            target=new BufferedImage(targetW,targetH,type);  
            Graphics2D g=target.createGraphics();  
            g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);  
            g.drawRenderedImage(source,AffineTransform.getScaleInstance(sx,sy));  
            g.dispose();  
        }
        ImageResizeModel imageResizeModel = new ImageResizeModel();
        imageResizeModel.setBuffedImage(target);
        imageResizeModel.setSx(sx);
        imageResizeModel.setSy(sy);
        return imageResizeModel;
    }
    
ImageResizeModel :
package com.syezon.webapp.util;

import java.awt.image.BufferedImage;

public class ImageResizeModel {

    private BufferedImage buffedImage;
    private double sx;//x轴缩放比例
    private double sy;//y轴缩放比例
    public BufferedImage getBuffedImage() {
        return buffedImage;
    }
    public void setBuffedImage(BufferedImage buffedImage) {
        this.buffedImage = buffedImage;
    }
    public double getSx() {
        return sx;
    }
    public void setSx(double sx) {
        this.sx = sx;
    }
    public double getSy() {
        return sy;
    }
    public void setSy(double sy) {
        this.sy = sy;
    }
    
}

看一下改进后的效果吧:

 

 

2,上传按钮改进:

页面上看到这样的框,大家是不是觉得体验不好啦?

那改成博客园这样的?刚发现的.... 说实在的,博客园的这个已经调到完美了:

事实上我们可以直接吵博客园的样式来做的现在做成这样啦:

    <div class="fileWrapper"  >
<a  class="fileButton">上传图片</a>
<input name="advImage" id="advImage" class="fileInput" type="file"  value="${advImage}" onchange="uploadImage()"/>
</div>

懂样式的可以看看啦,

一下两个就是关键啦:

opacity: 0;
font-size:100px;
.fileInput {
    cursor: pointer;
    height: 24px;
    opacity: 0;
    position: absolute;
    right: 0;
    top: 0;
    font-size:100px;
    filter:alpha(opacity=0);
    width: 200px;
}
.fileButton {
    background: none repeat scroll 0 0 #fc5d73;
    color: #FFFFFF;
    cursor: pointer;
    display: block;
    float: left;
    font-size: 12px;
    height: 20px;
    line-height: 20px;
    padding: 2px 4px;
    text-align: center;
    width: 96px;

}
 a:focus, a:active, a:hover {
    border: medium none;
    outline: medium none;
}

.fileWrapper {
    float: left;
    height: 24px;
    overflow: hidden;
    position: relative;
    width: 110px;cursor: pointer;
}

.fileWrapper a{color: #fff !important; text-decoration: none!important;cursor: pointer;}

 

效果:

 

3,关于window.showModalDialog 打开小页面缓存问题。

先前的代码没考虑这个问题,导致后期测试的时候才发现居然打开小页面后,下次再打开,修改的东西没有呈现....

解决方案也简单的,就是每次请求的url不一样就可以啦!

代码如下:随机数你懂的... 好像没必要 ++....先不管了...

var random = Math.round(1000); ;//每次请求的url保证不一样,决showModalDialog多次弹出时,取缓存页面问题
function show(rid)
{   random++;
   window.showModalDialog("toEditRole.html?roleId="+rid+"&random="+random,"window123","dialogHeight:510px;dialogWidth:650px;resizable:no;help:yes;status:no;scroll:auto");
}

 

4,取得本服务器的ip,端口

java中大家都熟悉用如下代码,在jsp中 还是在action层中取得ip地址和端口号:

    String basePath = request.getScheme() + "://" + request.getServerName() + ":"
        + request.getServerPort() + request.getContextPath() + "/";

那么在service层怎么办呢? 把request传进去不久可以啦...

是的,但是因为service层的话牵涉到业务,可能调用的方法比较多,如果每个都来个request实在是有点...

刚好用到那个dwr框架,可以直接取到request的信息:

    public static String getBasePath(){
        
        WebContext ctx = WebContextFactory.get();
        HttpServletRequest request = ctx.getHttpServletRequest();
            
        String basePath = request.getScheme() + "://" + request.getServerName() + ":"
        + request.getServerPort() + request.getContextPath() + "/";
        return basePath;
    }

但是,如果是action进来的service层方法,是不能使用这个方式的哦!

 

抛问题啦:

你们在项目里是怎么解决这个 要取得BasePath的问题的呢? 希望得到帮助!

 

 

让我们继续前行

----------------------------------------------------------------------

努力不一定成功,但不努力肯定不会成功。
共勉。

 

posted on 2013-03-04 17:08  每当变幻时  阅读(3543)  评论(6编辑  收藏  举报

导航