`
uule
  • 浏览: 6303323 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

移动端图片上传解决方案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编码和解码图片文件

 

代码:

效果:

 

 

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;
	}

 

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

    }
}

 

。。。

 

 

 

  • lrz.zip (29.8 KB)
  • 描述: JS包
  • 下载次数: 39
  • 大小: 70.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics