文件上傳+截圖+預覽升級版-我們到底能走多遠系列(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的問題的呢? 希望得到幫助!

 

 

讓我們繼續前行

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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM