现在科技太发达,移动设备像素越来越高,随便一张照片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:
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(";"); Iteratortype = 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 = ""; Iteratorit = 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));
}
}
。。。