功能簡介:javascript
在微信公衆號中,要開發一個照片上傳功能,能夠拍照,能夠選擇相冊圖片,能夠預覽。css
開發思路:html
用戶點擊上傳按鈕--》拍照或者選擇圖片--》調用上傳接口--》後來程序處理(生成縮略圖,旋轉圖片)上傳至fastdfs服務器--》返回上傳圖片的縮略圖地址和原圖片地址顯示在已上傳圖片區域。java
用戶對於已上傳的圖片能夠刪除.如刪除,對應fastdfs中的原始圖片和縮率圖一併刪除。ios
參考文章:ajax
http://blog.csdn.net/linlzk/article/details/48652635服務器
遇到的問題:微信
1,上傳圖片異步
採用表單方式上傳函數
<form class="uploadForm" enctype="multipart/form-data">
<input class="health-assay-info-id" name="healthAssayInfoId" type="hidden"><!--此到處理業務問題的id,上傳圖片後,對應的相關業務數據的id-->
<label class="btn-file">
<input type="file" accept="image/*" name="pics" capture="camera" onchange="form_pics.addImg(this);">
<img src="../images/upimg.png" alt="">
</label>
</form>
代碼中的紅色部分很重要。若是沒有此限制,部分安卓機型上沒法選擇照相機。
2,ios手機拍照,橫拍和豎拍旋轉問題
使用引入exif.js。獲取當前 照相機拍攝的照片的旋轉度數。
ps:此處下載 http://code.ciaoca.com/javascript/exif-js/
EXIF.getData(document.getElementById('imgElement'), function(){ var Orientation = EXIF.getTag(this, 'Orientation');
//ajaxSubmit上傳處理代碼,把 Orientation做爲參數,傳到後臺。
});
後臺處理:
if (picOrientation != null && picOrientation > 1) { int degree = 0; switch (picOrientation) { case 6: degree = 90; break; case 8: degree = 270; break; case 3: degree = 180; break; default: degree = 0; break; } }
旋轉圖片代碼(旋轉要從新計算圖片的寬高。http://www.oschina.net/code/snippet_818200_45972)
public static BufferedImage rotateImage(final BufferedImage bufferedImage, final int angle) { int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); int new_w = 0, new_h = 0; int new_radian = angle; if (angle <= 90) { new_w = (int)(width * Math.cos(Math.toRadians(new_radian)) + height * Math.sin(Math.toRadians(new_radian))); new_h = (int)(height * Math.cos(Math.toRadians(new_radian)) + width * Math.sin(Math.toRadians(new_radian))); } else if (angle <= 180) { new_radian = angle - 90; new_w = (int)(height * Math.cos(Math.toRadians(new_radian)) + width * Math.sin(Math.toRadians(new_radian))); new_h = (int)(width * Math.cos(Math.toRadians(new_radian)) + height * Math.sin(Math.toRadians(new_radian))); } else if (angle <= 270) { new_radian = angle - 180; new_w = (int)(width * Math.cos(Math.toRadians(new_radian)) + height * Math.sin(Math.toRadians(new_radian))); new_h = (int)(height * Math.cos(Math.toRadians(new_radian)) + width * Math.sin(Math.toRadians(new_radian))); } else { new_radian = angle - 270; new_w = (int)(height * Math.cos(Math.toRadians(new_radian)) + width * Math.sin(Math.toRadians(new_radian))); new_h = (int)(width * Math.cos(Math.toRadians(new_radian)) + height * Math.sin(Math.toRadians(new_radian))); } BufferedImage toStore = new BufferedImage(new_w, new_h, BufferedImage.TYPE_INT_RGB); Graphics2D g = toStore.createGraphics(); AffineTransform affineTransform = new AffineTransform(); affineTransform.rotate(Math.toRadians(angle), width / 2, height / 2); if (angle != 180) { AffineTransform translationTransform = findTranslation(affineTransform, bufferedImage, angle); affineTransform.preConcatenate(translationTransform); } g.setColor(Color.WHITE); g.fillRect(0, 0, new_w, new_h); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.drawRenderedImage(bufferedImage, affineTransform); g.dispose(); return toStore; }
3.使用
EXIF.getData獲取獲取拍攝方向時,感受此方式是異步的
若是這樣寫
var Orientation = null; EXIF.getData(document.getElementById('imgElement'), function(){ Orientation = EXIF.getTag(this, 'Orientation'); }); //ajaxSubmit上傳處理代碼,把 Orientation做爲參數,傳到後臺。
就會先去執行上傳,而後才執行
EXIF.getData的回調函數獲取到Orientation 。尚未想到有什麼好的解決方案,索性把上傳代碼邏輯寫到了EXIF.getData的回調函數裏面。
4,展現大圖
展現大圖時須要計算手機屏幕的分辨率。個人策略以下
var windowW = $(window).width(); var windowH = $(window).height(); var realWidth = this.width; var realHeight = this.height; var imgWidth, imgHeight; var scale = 0.8; if(realHeight>windowH*scale && realWidth>windowW) { imgWidth = windowW; imgHeight = imgWidth/realWidth*realHeight; } else if(realHeight>windowH*scale){ imgHeight = windowH*scale; imgWidth = imgHeight/realHeight*realWidth; } else if(realWidth>windowW){ imgWidth = windowW; imgHeight = imgWidth/realWidth*realHeight; } else { imgWidth = realWidth; imgHeight = realHeight; } $("#bigimg").css("width",imgWidth);
若是實際寬度>屏幕寬度,保證寬是沾滿屏幕,調整高度