现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动端你不能去限制图片大小,让用户先处理图片再上传,这样不现实。所以理解的解决方案就是在上传先进行图片压缩,然后再把压缩后的图片上传到服务器。
localResizeIMG,它会对图片进行压缩成你指定宽度及质量度并转换成base64图片格式,那么我们就可以把这个base64通过ajax传到后台,再进行保存,先压缩后上传的目的就达到了。
处理过程:
LocalResizeIMG压缩图片
Ajax Post图片base64到后台
后台接收base64并保存,返回状态
包含:
LocalResizeIMG.js(插件主体,压缩图片)
mobileBUGFix.mini.js(移动端的补丁,包括MegaPixImage.js)
exif.js
LocalResizeIMG前端HTML5本地压缩图片上传,兼容移动设备IOS,android
源码:https://github.com/think2011/localResizeIMG
移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传
HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(一)
exif.js(lrz.js控件中使用了):
Exif.js 提供了 JavaScript 读取图像的原始数据的功能扩展,例如:拍照方向、相机设备型号、拍摄时间、ISO 感光度、GPS 地理位置等数据。
代码:
效果:
HTML:
- <!-- 上传图片时显示“正在上传..请等待”,上传后显示各图片-->
- <li class="pic-list"></li>
- <li class="upload">
- <input type="file" accept="image/*" id="cameraInput" name="cameraInput">
- 上传图片
- </li>
- <!-- 引用-->:
- <script type="text/javascript" src="${staticServerUrl}/js/lrz/mobileFix.mini.js?v=20150704"></script>
- <script type="text/javascript" src="${staticServerUrl}/js/lrz/exif.js?v=20150704"></script>
- <script type="text/javascript" src="${staticServerUrl}/js/lrz/lrz.js?v=20150704"></script>
JS:
- var input = document.querySelector('#cameraInput');
- var types = [".jpg",".jpeg",".gif",".png"];
- var mpiArr = [];
- var index = 0;
- input.onchange = function () {
- var file = this.files[0];
- var span = document.createElement('span');
- var fileName = file.name;
- var imgSize = file.size;
- if(!checkFileType(fileName)) {
- alert("文件类型必须为jpg/jpeg/gif/png");
- return;
- }
- if(imgSize > 3*1024*1024) { //大于2M
- alert("请上传小于3M的文件");
- return;
- }
- document.querySelector('.pic-list').appendChild(span);
- span.innerHTML = '<p>正在上传..请等待</p>';
- lrz(file, {
- before: function() {
- },
- fail: function(err) {
- //console.error(err);
- },
- always: function() {
- },
- done: function (results) {
- setTimeout(function () {
- $.post(
- "/ajax/uploadImg.do",
- {
- imgBase64: results.base64,
- imgSize: results.base64.length, // 校验用,防止未完整接收
- imgName : fileName
- },
- function (data) {
- var rData = eval('(' + data + ')');
- var img = document.createElement('img');
- var timestamp=new Date().getTime();
- var idx = "img" + fileName.substring(0, fileName.indexOf(".")) + timestamp;
- $(span).attr("class" ,"imgSpan");
- $(span).attr("id" ,idx);
- $(span).attr("name" ,rData.path);
- if(!rData.ret || rData.content != "ok") {
- span.innerHTML = '<p>上传失败</p>';
- } else {
- span.innerHTML = '<p>上传成功</p>';
- //用于上传完成后直接展示图片
- var mpImg = new MegaPixImage(file);
- mpImg.render(img, { maxWidth: 150, maxHeight: 150, quality: 0.5 });
- mpiArr.push({"id":idx,"mpi":mpImg});
- span.innerHTML = "";
- span.appendChild(img);
- }
- }
- );
- }, 100);
- }
- });
- };
- //用于点击上传展示的图片时,往指定位置(ueditor编辑器里)插入该图片
- $(document).on("click",".imgSpan",function(){
- var id = $(this).attr("id");
- var imgSrc = $(this).attr("name");
- var mpi;
- $.each(mpiArr, function(index,value){
- if(value.id == id) {
- mpi = value.mpi;
- }
- });
- var idx = id + index++;
- //ueditor的对象um
- um.focus();
- um.execCommand('inserthtml',"<img id='" + idx + "' src='" + imgSrc + "' _src='" + imgSrc + "' ></img>");
- mpi.render($(window.frames["1"].document).find("#"+idx).get(0), { maxWidth: 150, maxHeight: 150, quality: 0.5, _src: imgSrc });
- });
- String.prototype.endWith=function(str){
- if(str==null||str==""||this.length==0||str.length>this.length)
- return false;
- if(this.substring(this.length-str.length)==str)
- return true;
- else
- return false;
- return true;
- }
- function checkFileType(name) {
- var flag = false;
- $.each(types,function(index,value) {
- if(name.endWith(value)) {
- flag = true;
- }
- })
- return flag;
- }
后台:
入口:
- /**
- * 上传图片
- */
- public String uploadImg() {
- if(!checkFileType(getFileExt(imgName))) {
- CDO result = new CDO();
- result.setBooleanValue("ret", false);
- result.setStringValue("content", "文件应为jpg,jpeg,gif,png");
- ajaxForAction(response, result.toJSON());
- return null;
- }
- String imgFilePath = saveBase64toLocal(getFileName(imgName));
- String returnStr = uploadtoImgServer(imgFilePath);
- ajaxForAction(response, returnStr);
- return null;
- }
- /**
- * 文件类型判断
- */
- private boolean checkFileType(String fileName) {
- String imgAllowTypes = ProPertiesUtil.getValue("/topic.properties", "img_allow_types");
- String[] allowFiles = imgAllowTypes.split(";");
- Iterator<String> type = Arrays.asList(allowFiles).iterator();
- while (type.hasNext()) {
- String ext = type.next();
- if (fileName.toLowerCase().endsWith(ext)) {
- return true;
- }
- }
- return false;
- }
- /**
- * 获取文件扩展名
- */
- private String getFileExt(String fileName) {
- return fileName.substring(fileName.lastIndexOf("."));
- }
- /**
- * 依据原始文件名生成新文件名
- */
- private String getFileName(String fileName) {
- String radomStr = new SimpleDateFormat("yyyyMMddHHmmsss").format(new Date());
- return fileName.substring(0,fileName.lastIndexOf(".")) + radomStr + this.getFileExt(fileName);
- }
- /**
- * 保存图片到临时文件目录
- * #本地临时图片存储地址
- * tmp_img_path=/upload
- * #允许上传的图片类型
- * img_allow_types=.jpg;.jpeg;.gif;.png
- */
- private String saveBase64toLocal(String fileName) {
- String imgFilePath = "";
- Long userId = getLoginID();
- logger.info("添加图片,用户id:"+userId+",版块id:"+boardID+",图片名:"+imgName);
- int index = imgBase64.indexOf(";base64,");
- String base64Str = imgBase64.substring(index + ";base64,".length());
- String tmpImgPath = ProPertiesUtil.getValue("/abc.properties", "tmp_img_path");
- imgFilePath = getPhysicalPath(tmpImgPath) + File.separator + fileName;// 新生成的图片
- BASE64Decoder decoder = new BASE64Decoder();
- OutputStream out = null;
- try {
- // Base64解码
- byte[] b = decoder.decodeBuffer(base64Str);
- for (int i = 0; i < b.length; ++i) {
- if (b[i] < 0) {// 调整异常数据
- b[i] += 256;
- }
- }
- // 生成jpeg图片
- out = new FileOutputStream(imgFilePath);
- out.write(b);
- out.flush();
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- } finally {
- try{
- out.close();
- }catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
- }
- logger.info("成功添加图片,用户id:"+userId+",版块id:"+boardID+",图片位置:"+ imgFilePath);
- return imgFilePath;
- }
- /**
- * 根据传入的虚拟路径获取物理路径
- */
- private String getPhysicalPath(String savePath) {
- return ServletActionContext.getServletContext().getRealPath(savePath);
- }
- /**
- * 上传图片到服务器
- * httpclient-4.0.1.jar
- * httpmime-4.0.1.jar
- * img_server_path=http://...com/BBSPicServlet
- */
- private String uploadtoImgServer(String filePath) {
- String returnStr = "";
- Long userId = getLoginID();
- logger.info("上传图片服务器,用户id:"+userId+",版块id:"+boardID+",图片路径:"+filePath);
- String IMAGE_FTP_PATH = ProPertiesUtil.getValue("/server.properties", "img_server_path");
- HttpClient httpclient = new DefaultHttpClient();
- HttpPost post = new HttpPost(IMAGE_FTP_PATH);
- File file = new File(filePath);
- FileBody fileBody = new FileBody(file);
- try {
- MultipartEntity entity = new MultipartEntity();
- entity.addPart("file", fileBody);
- post.setEntity(entity);
- HttpResponse response = httpclient.execute(post);
- logger.info("图片服务器返回code:" + response.getStatusLine().getStatusCode());
- if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
- HttpEntity entitys = response.getEntity();
- if (entitys != null) {
- //resultLen = entity.getContentLength();
- returnStr = EntityUtils.toString(entitys);
- }
- }
- httpclient.getConnectionManager().shutdown();
- //删除本地
- file.delete();
- } catch (UnsupportedEncodingException e) {
- logger.error(e.getMessage(), e);
- } catch (ClientProtocolException e) {
- logger.error(e.getMessage(), e);
- } catch (IOException e) {
- logger.error(e.getMessage(), e);
- }
- logger.info("成功上传图片服务器,用户id:"+userId+",版块id:"+boardID+",服务器返回:"+returnStr );
- return returnStr;
- }
- package com.duogou9g.bbs;
- import java.io.File;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.Date;
- import java.util.Iterator;
- import java.util.List;
- import java.util.UUID;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.FileUploadException;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- import org.apache.log4j.Logger;
- import com.duogou9g.DateUtils;
- import com.duogou9g.PICServlet;
- import com.duogou9g.ProPertiesUtil;
- import com.util.KingCloudUtil;
- /**
- * bbs 图片上传
- *
- * @author Administrator
- *
- */
- public class BBSPicServlet extends HttpServlet {
- private static String savePath = ProPertiesUtil.getValue(
- "/path.properties", "bbsimgpath");
- private Logger logger = Logger.getLogger(PICServlet.class);
- public void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- // TODO Auto-generated method stub
- super.doGet(req, resp);
- }
- private boolean isEmpty(String str) {
- if (str == null || "".equals(str.trim()))
- return true;
- return false;
- }
- private boolean checkInt(String str) {
- String reg = "^[0-9]+$";
- Pattern pattern = Pattern.compile(reg);
- Matcher matcher = pattern.matcher(str);
- return matcher.matches();
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- // TODO Auto-generated method stub
- String filenames = "";
- String res = "";
- String datap = "";
- // 如果有尺寸,检查尺寸
- logger.info("==get==================");
- String picWidth = request.getParameter("picWidth");
- String picHeigth = request.getParameter("picHeigth");
- if (!isEmpty(picWidth) || !isEmpty(picHeigth)) {
- if (!checkInt(picWidth) || !checkInt(picHeigth)) {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- out.println("{'ret':'false','content':'尺寸错误'}");
- out.close();
- return;
- }
- }
- DiskFileItemFactory fac = new DiskFileItemFactory();
- ServletFileUpload upload = new ServletFileUpload(fac);
- upload.setHeaderEncoding("UTF-8");
- upload.setFileSizeMax(2 * 1024 * 1024);
- List fileList = null;
- try {
- fileList = upload.parseRequest(request);
- } catch (FileUploadException e) {
- // TODO Auto-generated catch block
- logger.error(e.getMessage(), e);
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- out.println("{'ret':'false','content':'图片过大,不能大于500K'}");
- out.close();
- return;
- }
- String name = "";
- String extName = "";
- long size = 0;
- String fileName = "";
- Iterator<FileItem> it = fileList.iterator();
- while (it.hasNext()) {
- FileItem item = it.next();
- if (!item.isFormField()) {
- name = item.getName();
- if (name == null || name.trim().equals("")) {
- continue;
- }
- size = item.getSize();
- if ("".equals(name) || size == 0) {
- break;
- }
- String t_name = name.substring(name.lastIndexOf("\\") + 1);
- logger.info("=================" + t_name);
- String t_ext = t_name.substring(t_name.lastIndexOf(".") + 1);
- String[] allowedExt = { "jpg", "jpeg", "gif", "png" };
- int allowFlag = 0;
- int allowedExtCount = allowedExt.length;
- for (; allowFlag < allowedExtCount; allowFlag++) {
- if (allowedExt[allowFlag].equals(t_ext.toLowerCase()))
- break;
- }
- if (allowFlag == allowedExtCount) {
- res = "文件应为: jpg,jpeg,gif,png";
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- out.println("{'ret':'false','content':'文件应为jpg,jpeg,gif,png'}");
- out.close();
- return;
- } else {
- if (name.lastIndexOf(".") >= 0) {
- extName = name.substring(name.lastIndexOf("."));
- }
- String all = DateUtils.simpleDateFormat(
- "yyyy-MM-dd HH:mm:ss", new Date());
- String hour = all.split(" ")[1].split(":")[0];
- String aa[] = all.split(" ")[0].split("-");
- // savePath = savePath+"/"+aa[0]+"/"+aa[1]+"/"+aa[2];
- datap = "/" + aa[0] + "/" + aa[1] + "/" + aa[2] + "/"+ hour;
- String newDir = savePath + datap;
- File file = new File(newDir);
- if (!file.exists()) {
- file.mkdirs();
- }
- fileName = UUID.randomUUID().toString().replaceAll("-", "");
- File saveFile = new File(newDir + "/" + fileName + extName);
- filenames = fileName + extName;
- String bucket = ProPertiesUtil.getValue(
- "/accesskey.properties", "bbsbucket");
- Boolean tokingok = false;
- try {
- item.write(saveFile);
- // 如果有尺寸,检查尺寸
- if (!isEmpty(picWidth) || !isEmpty(picHeigth)) {
- java.awt.image.BufferedImage bi = javax.imageio.ImageIO
- .read(saveFile);
- if (bi.getWidth() != Integer.parseInt(picWidth)
- || bi.getHeight() != Integer
- .parseInt(picHeigth)) {
- saveFile.delete();
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- out.println("{'ret':'false','content':'文件尺寸不对'}");
- out.close();
- return;
- }
- // 发送到云
- tokingok = KingCloudUtil.uploadObjectByFile(bucket,
- "img" + datap + "/" + filenames, saveFile);
- // 本地删除
- } else {
- // 发传送到云
- tokingok = KingCloudUtil.uploadObjectByFile(bucket,
- "img" + datap + "/" + filenames, saveFile);
- }
- saveFile.delete();
- logger.info("====ok====="+ filenames);
- if (tokingok == true) {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- String str = "{'ret':'true','content':'ok','path':'"
- + ProPertiesUtil.getValue(
- "/accesskey.properties",
- "bbsimgurl")
- + "/img"
- + datap
- + "/"
- + filenames + "'}";
- out.println(str);
- out.close();
- } else {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- String str = "{'ret':'false','content':'云出错'}";
- out.println(str);
- out.close();
- }
- } catch (Exception e) {
- res = "false";
- logger.error(e.getMessage(), e);
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- out.println("{'ret':'false','content':'写入错误'}");
- out.close();
- }
- }
- }
- }
- }
- public static void main(String[] args) {
- System.out.println(UUID.randomUUID().toString().replaceAll("-", ""));
- System.out.println(DateUtils.simpleDateFormat("yyyyMMdd", new Date()));
- String aa = "E:/Seller20110928/upload/";
- File file = new File(aa);
- if (!file.exists()) {
- file.mkdirs();
- }
- }
- }
读取时:
读取时,也得把编辑框里的内容转换为BASE64Code,convertImgBASE64Code,这样才可正常读取
若不转换,编辑框里显示的是纯文本,图片显示的是路径,不会展示
- String contentWithBase64Img = HtmlUtil.convertImgBASE64Code(cdoTopic.getStringValue("content"));
- cdoTopic.setStringValue("content",URLEncoder.encode(contentWithBase64Img,"UTF-8"));
JS:
- <input type="hidden" id="srcContent" name="srcContent" value="${cdoTopic.getStringValue('content')}" />
- $(document).ready(function(){
- var srcContent = $("#srcContent").val();
- um.addListener("ready", function () {
- um.execCommand('inserthtml', decodeURIComponent(srcContent.replace(/\+/g, '%20')));
- var imgArr = $(window.frames["1"].document).find("img");
- for(var i = 0 ; i < imgArr.length; i++){
- var imgSrc = $(imgArr[i]).attr("src");
- var mpImg = new MegaPixImage(imgArr[i]);
- mpImg.render(imgArr[i], { maxWidth: 150, maxHeight: 150, quality: 0.5, _src: imgSrc });
- }
- });
- });
工具类:
- import java.io.IOException;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import org.jsoup.Jsoup;
- import org.jsoup.nodes.Document;
- import org.jsoup.nodes.Element;
- import org.jsoup.select.Elements;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import sun.misc.BASE64Encoder;
- public class HtmlUtil {
- private static Logger logger = LoggerFactory.getLogger(HtmlUtil.class);
- public static String convertImgLazyLoad(String bodyFragment){
- Document doc = Jsoup.parseBodyFragment(bodyFragment);
- Elements imgs = doc.getElementsByTag("img");
- for(int i=0; i< imgs.size(); i++){
- Element img = imgs.get(i);
- img.addClass("lazy");
- img.attr("data-original", img.attr("src"));
- img.attr("src", ProPertiesUtil.getValue("/server.properties", "staticServer") + "/img/loading.gif");
- }
- return doc.body().html();
- }
- public static String convertImgBASE64Code(String bodyFragment){
- Document doc = Jsoup.parseBodyFragment(bodyFragment);
- Elements imgs = doc.getElementsByTag("img");
- for(int i=0; i< imgs.size(); i++){
- Element img = imgs.get(i);
- String src = img.attr("src");
- String base64Str = "";
- try{
- base64Str = getImageBASE64Code(src);
- }catch (IOException e){
- logger.error(e.getMessage(), e);
- }
- img.attr("_src", img.attr("src"));
- img.attr("src", base64Str);
- }
- return doc.body().html();
- }
- /**
- * 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
- *
- * @param imgUrl
- * @return
- * @throws IOException
- */
- private static String getImageBASE64Code(String imgUrl) throws IOException {
- URL url = new URL(imgUrl);
- HttpURLConnection conn = (java.net.HttpURLConnection) url.openConnection();
- if (conn.getResponseCode() == 200) {
- java.io.InputStream is = conn.getInputStream();
- java.io.ByteArrayOutputStream baos =
- new java.io.ByteArrayOutputStream();
- int buffer = 1024;
- byte[] b = new byte[buffer];
- int n = 0;
- while ((n = is.read(b, 0, buffer)) > 0) {
- baos.write(b, 0, n);
- }
- // String s = new String(baos.toByteArray(), "UTF-8");
- is.close();
- baos.close();
- // 对字节数组Base64编码
- BASE64Encoder encoder = new BASE64Encoder();
- return "data:image/jpeg;base64," + encoder.encode(baos.toByteArray());
- // return encoder.encode(baos.toByteArray());
- }
- return "";
- }
- public static void main(String[] args){
- String content = "<img src=\"http://img.1more.com/bbs/2015/07/03/14/0ccb5349b8d246f28f64dbf9acd2161f.jpg\" alt=\"\" />gdsahdshsdhdsh<span>asdads";
- // String content = "//img.1more.com/bbs/2015/07/03/14/0ccb5349b8d246f28f64dbf9acd2161f.jpg\" alt=\"\" />gdsahdshsdhdsh<span>asdads";
- System.out.println(convertImgLazyLoad(content));
- }
- }
。。。