现在科技太发达,移动设备像素越来越高,随便一张照片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; }
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)); } }
。。。
相关推荐
移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传,(H5)FormData+AJAX异步上传文件
下面通过文字说明和代码分析的方式给大家分享移动端图片上传之localResizeIMG先压缩后ajax无刷新上传,具体实现过程请看下文。 现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc...
在现代Web应用中,"Ajax无刷新上传图片"是一个常见的需求,它允许用户在不刷新整个页面的情况下上传图片,提供更好的用户体验。Ajax(Asynchronous JavaScript and XML)技术结合IFrame可以实现这一功能,使得文件...
移动端图片上传,html5+PHP实现,现在移动端存储照片都比较大,所以在上传之前我们需要进行压缩处理。简单写一下思路: 1.选择完图片通过html5的FileReader拿到base64的图片 2.创建一个Image对象,将base64图片作为...
本项目提供了一个完整的移动端图片上传解决方案,包括前端H5实现和PHP后台处理代码,适用于快速集成到你的项目中。 首先,我们关注前端部分。H5图片上传主要依赖于HTML5的新特性,如File API和FormData对象。File ...
为了解决这一问题,ASP(Active Server Pages)结合AJAX(Asynchronous JavaScript and XML)技术,实现了无刷新文件上传,同时还提供了进度条显示,提高了交互性。本文将深入探讨这种技术的实现原理及步骤。 一、...
无刷新上传图片的核心是利用AJAX的异步特性,用户选择图片后,前端通过JavaScript读取文件内容,然后使用XMLHttpRequest对象将图片数据发送到后台服务器。服务器接收到数据后进行处理(如存储、缩略图生成等),最后...
ajax + asp无刷新文件异步上传程序,并有进度条实时显示上传进度!ajax + asp无刷新文件异步上传程序,并有进度条实时显示上传进度!ajax + asp无刷新文件异步上传程序,并有进度条实时显示上传进度!ajax + asp无...
总的来说,这个移动端图片压缩上传插件提供了一套完整的解决方案,涵盖了图片压缩和上传的各个环节,而且由于是纯JavaScript实现,它的性能和兼容性都得到了优化。对于希望在移动应用中实现高效图片处理的开发者来说...
本实例提供了完整的Java AJAX无刷新分页解决方案,允许用户在不重新加载整个页面的情况下浏览多页数据,提高网页交互的效率。下面我们将详细探讨这个实例中的关键知识点。 1. **AJAX基础**:AJAX是一种在后台与...
asp无刷新上传文件ajax上传文件 请将本程序放到你的虚拟主机上运行,如果本地有iis也可以。有些同学有简易iis服务器,不适用本程序的,因为有部分中文字符不能识别导致无法运行。 如果需要上传多文件可以把index....
在现代Web应用中,"Ajax无刷新文件上传(带进度条)"是一个常见且重要的功能,它极大地提升了用户体验。Ajax(Asynchronous JavaScript and XML)技术使得网页可以在不重新加载整个页面的情况下与服务器交换数据并更新...
"C# jQuery AJAX 预览并无刷新上传图片"的主题涵盖了多项技术,旨在提供流畅、直观的用户体验。以下是对这些知识点的详细阐述: 1. **jQuery**:jQuery是一个强大的JavaScript库,它简化了HTML文档遍历、事件处理、...
**Ajax无刷新上传图片** Ajax无刷新上传图片的基本流程包括前端交互、数据传输和后端处理。在前端,使用jQuery的`$.ajax`或`$.fileupload`方法可以方便地实现文件上传。以下是一个基本的示例: ```javascript $("#...
**Ajax无刷新文件上传技术详解** 在Web开发中,用户经常需要进行文件上传操作,传统的文件上传方式通常会刷新整个页面,导致用户体验下降。而Ajax技术的出现,为实现无刷新文件上传提供了可能。"艾恩Ajax无刷新文件...
Ajax无刷新多文件(图片)上传及删除技术是现代网页应用中常见的功能,它极大地提升了用户体验,使得用户在不刷新整个页面的情况下即可完成文件或图片的上传与删除操作。Ajax,全称Asynchronous JavaScript and XML...