功能简介:
在微信公众号中,要开发一个照片上传功能,可以拍照,可以选择相册图片,可以预览。
开发思路:
用户点击上传按钮--》拍照或者选择图片--》调用上传接口--》后来程序处理(生成缩略图,旋转图片)上传至fastdfs服务器--》返回上传图片的缩略图地址和原图片地址显示在已上传图片区域。
用户对于已上传的图片可以删除.如删除,对应fastdfs中的原始图片和缩率图一并删除。
参考文章:
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);
如果实际宽度>屏幕宽度,保证宽是沾满屏幕,调整高度