浏览器环境下压缩图片的实现 图片转换为BASE64码传输 服务器端图片压缩 公众号开发
目前为止 在浏览器端实现图片压缩 方式大致是通过HTML5的canvas对象来实现的
核心函数是 var compressedImageDataURL = canvas.toDataURL(mimeType, 10 / 100)
简单小例子整体流程:
本例子使用了 Jquery.jar
定制编写压缩图片函数
编写界面以及设置对象
编写服务器端图片base64编码处理函数(生成图片)
提示界面
编写pressPicFun.js
window.URL = window.URL || window.webkitURL
function isCanvasBlank (canvas) {
var blank = document.createElement('canvas')
blank.width = canvas.width
blank.height = canvas.height
return canvas.toDataURL() == blank.toDataURL()
}
//pFileType 文件base类型 pVids base64码存的text文本框的ID值
function ppp(pFileType,pVids){
//画图压缩图片数据
var sourceImage = J_Image
var canvas = J_ImageCanvas
var context = canvas.getContext('2d')
if (!isCanvasBlank(canvas)) {
context.clearRect(0, 0, canvas.width, canvas.height)
}
var ima = $("#J-Image");
if(sourceImage.naturalWidth == 0 ){
canvas.width = $("#J-Image").width();
}else{
canvas.width = sourceImage.naturalWidth
}
if(sourceImage.naturalHeight == 0 ){
canvas.width = $("#J_Image").height();
}else{
canvas.height = sourceImage.naturalHeight
}
context.drawImage(sourceImage, 0, 0)
//压缩图片数据 并赋值
var canvas = J_ImageCanvas
var mimeType = pFileType || 'image/png'
J_CompressedImage.removeAttribute('src')
var compressedImageDataURL = canvas.toDataURL(mimeType, 10 / 100)
if(pVids != null && pVids != ''){
$("#"+pVids).val(compressedImageDataURL); //赋值到指定的文本域
console.log("pVids--==="+pVids +" 赋值完毕 清空数据 ");
pVids = '';
compressedImageDataURL='';
}
compressSuccess = true
console.log('yasuo hou compressSuccess='+compressSuccess)
}
//压缩图片的函数引用 obj 文件选择框 , vid base码存放位置
var presspic = function(obj,vid){
var file
var fileType
var url
var compressedImageDataURL
var compressSuccess = false
var contentType
//文件变化 读取文件
var fileName
file = obj.files[0];
fileName = file.name;
fileType = file.type || 'image/' + fileName.substr(fileName.lastIndexOf('.') + 1);
console.log("filename=" + fileName +" fileType = " + fileType);
console.log('yasuo qian1 compressSuccess='+compressSuccess)
//转换图片为dataUrl数据
var fileReader = new FileReader()
J_Image.removeAttribute('src')
fileReader.onload = function (e) {
var dataURL = e.target.result
J_Image.src = dataURL //传递数据
}
fileReader.readAsDataURL(file)
ppp(fileType,vid);
}
2 编写界面以及dom对象配置
<!--引用对象 -->
<img id="J_Image" alt="Image" >
<canvas id="J_ImageCanvas" ></canvas>
<img id="J_CompressedImage" >
<p id="J_CompressedImageDataURL" class="single-line"></p>
界面布局配置 并通过file变化来执行 压缩图片的操作
<form id="multipartyForm" target="uploadFrame" action="./servlet/picPress" method="POST" enctype="multipart/form-data">
<input type="file" accept="image/*" capture="camera" onchange="presspic(this,'file1');">
<input type="text" name="file1" id="file1" value="1">
<hr/>
<input type="file" accept="image/*" capture="camera" onchange="presspic(this,'file2')">
<input type="text" name="file2" id="file2" value="2">
<input type="submit" value="上传图片">
</form>
</div>
3 提交数据到服务器 编写服务器端程序(本实例是Servlet控制器)
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("post");
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
DiskFileItemFactory dfif = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(dfif);
try {
List<FileItem> items = sfu.parseRequest(request);
for (int i = 0; i < items.size(); i++) {
FileItem item = items.get(i);
// 要判断是一个普通的表单域还是上传文件域
if (item.isFormField()) {
// 是一个普通的表单域
String name = item.getFieldName();
String value = item.getString();
//System.out.println(name + ":" + value.substring(0,1000));
//图片通过base64码 传输, 切此base码是经过压缩的, 后台对文件在进行二次压缩 若图片大于100k 服务器在进行二次压缩
WeixinFileUtil.uploadYsBaseFile(request, name, value);
}
}
} catch (Exception e) {
e.printStackTrace();
response.getWriter().write("添加失败");
}
JSONObject json = new JSONObject();
json.put("success", "添加成功");
response.getWriter().write(json.toString());
out.flush();
out.close();
}
4 获取到了上传的BASE64码 对其进行处理 生成图片文件 并对图片进行二次压缩处理
public static String uploadYsBaseFile(HttpServletRequest request,
String fileParamName,String fileValue) throws Exception {
String rsFilePath = "";
// 获得文件
String baseYsFile = fileValue; //request.getParameter(fileParamName);
System.out.println("a="+baseYsFile);
if(baseYsFile == null){
return null;
}
// 获得文件名
String endTag = "."+ baseYsFile.split(",")[0].split(":")[1].split(";")[0].split("/")[1];
String targetFileName = UUID.randomUUID().toString()
.replaceAll("-", "")
+ endTag;
System.out.println("target =" + targetFileName);
// 文件存放地址
String tagFileDir = request.getSession().getServletContext().getRealPath("/")
+ "\\weixinFiles\\";
File fileDir = new File(tagFileDir);
if (!fileDir.exists()) {
fileDir.mkdir();
}
rsFilePath = "\\weixinFiles\\" + targetFileName ;
System.out.println(rsFilePath);
Base64ImgtoFile(baseYsFile, tagFileDir + targetFileName);
return rsFilePath;
}
//base64字符串转化成图片
public static void Base64ImgtoFile(String dataURI,String FileAbsPath)
{ //对字节数组字符串进行Base64解码并生成图片
if (dataURI == null) //图像数据为空
return ;
BASE64Decoder decoder = new BASE64Decoder();
try
{
String dataImg = dataURI.split(",")[1];
//Base64解码
byte[] b = decoder.decodeBuffer(dataImg);
for(int i=0;i<b.length;++i)
{
if(b[i]<0)
{//调整异常数据
b[i]+=256;
}
}
//生成jpeg图片
File createNewFile = new File(FileAbsPath);
if(createNewFile.exists()){
createNewFile.createNewFile();
}
OutputStream out = new FileOutputStream(FileAbsPath);
out.write(b);
out.flush();
out.close();
//二次压缩 对于大于100K的图片进行二次压缩
if(createNewFile.length()/1000 > 100){
ImagePress.pressImg(FileAbsPath);
}else{
System.out.println("no no no ");
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
//服务器端图片压缩
public static void pressImg(String filePath){
try {
System.out.println("压缩图片");
Thumbnails.of(filePath).scale(0.5f).toFile(filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
上面使用的技术: 通过HTML5浏览器内压缩图片; 通过 commons-fileupload-1.2.1.jar 服务器端获取base64图片编码;
通过编码还原为图片 并重新生成图片写入服务器目录weixinFiles; 之后通过谷歌的图片压缩类 thumbnailator-0.4.8.jar 对图片进行二次压缩,这样 几兆的图片会被压缩到几十K 存储在服务器上。
如有疑问 请留言 欢迎提供建议
评论已有 0 条