移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传

阅读更多

现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动端你不能去限制图片大小,让用户先处理图片再上传,这样不现实。所以理解的解决方案就是在上传先进行图片压缩,然后再把压缩后的图片上传到服务器

localResizeIMG,它会对图片进行压缩成你指定宽度及质量度并转换成base64图片格式,那么我们就可以把这个base64通过ajax传到后台,再进行保存,先压缩后上传的目的就达到了。

 

处理过程:

LocalResizeIMG压缩图片

Ajax Post图片base64到后台

后台接收base64并保存,返回状态

 

包含:

LocalResizeIMG.js(插件主体,压缩图片)

mobileBUGFix.mini.js(移动端的补丁,包括MegaPixImage.js)

exif.js

 

在线任意图片转Base64编码工具 - aTool在线工具

 

LocalResizeIMG前端HTML5本地压缩图片上传,兼容移动设备IOS,android

源码:https://github.com/think2011/localResizeIMG

 

使用lrz压缩上传图片,后台使用java

移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传

HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(一)

 

exif.js(lrz.js控件中使用了):

Exif.js 提供了 JavaScript 读取图像的原始数据的功能扩展,例如:拍照方向、相机设备型号、拍摄时间、ISO 感光度、GPS 地理位置等数据。

Exif.js 读取图像的元数据

利用exif.js解决ios手机上传竖拍照片旋转90度问题

 

(java)利用BASE64编码和解码图片文件

 

代码:

效果:

 
移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传_第1张图片
 

HTML:


  • 上传图片
  •  

    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 = '

    正在上传..请等待

    '; 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 = '

    上传失败

    '; } else { span.innerHTML = '

    上传成功

    '; //用于上传完成后直接展示图片 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',"");
    	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 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;
    	}

     

    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;
    
    
    /**
     * 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 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:

    
    
    $(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 = "\"\"gdsahdshsdhdshasdads";
    //        String content = "//img.com/bbs/2015/07/03/14/0ccb5349b8d246f28f64dbf9acd2161f.jpg\" alt=\"\" />gdsahdshsdhdshasdads";
            System.out.println(convertImgLazyLoad(content));
    
        }
    }

     

    。。。

     

     

     

    • lrz.zip (29.8 KB)
    • 描述: JS包
    • 下载次数: 39
    • 移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传_第2张图片
    • 大小: 70.1 KB
    • 查看图片附件

    你可能感兴趣的:(移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传)