移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传
现在科技太发达,移动设备像素越来越高,随便一张照片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));
}
}
。。。