我們到底能走多遠系列(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的問題的呢? 希望得到協助!
讓我們繼續前行
----------------------------------------------------------------------
努力不一定成功,但不努力肯定不會成功。
共勉。