需求:做一个电子签章图片上传,然后在线截取并上传到后台,再对图片进行格式化处理,包括位深度8位,gif格式,删除元数据
实现:
1,先在前台使用了一个cropbox.js的插件,这个插件能实现图片上传并在线预览剪切等功能,并将截取后的图片以base64的格式传向后台
var options = {
thumbBox: '.thumbBox',
spinner: '.spinner',
imgSrc: ''
}
var cropper = $('.imageBox').cropbox(options);
$('#upload-file').on('change', function () {
var reader = new FileReader();
reader.onload = function (e) {
options.imgSrc = e.target.result;
cropper = $('.imageBox').cropbox(options);
$('#spinner').html('');
}
reader.readAsDataURL(this.files[0]);
})
$('#btnCrop').on('click', function () {
//判断是否发生改变
var bigContent = $('#spinner').html();
if(bigContent.indexOf("图片") > 0){
$window.alert("图片没上传,请不要点击裁切")
return false;
}
var img = cropper.getDataURL();
$('#croppedAdd').html('');
$('#croppedAdd').append('<img src="' + img + '" style="height: 200px;width: 200px;border: 1px solid #000000;" id="truePic" align="absmiddle" >');
})
2,在后台接收base64, 去掉格式头,然后先生成一个png格式的图片
base64 = base64.split(",")[1];
BASE64Decoder decoder = new BASE64Decoder();
String FilePath = "";
try{
//Base64解码
byte[] b = decoder.decodeBuffer(base64);
for(int i=0;i<b.length;++i) {
if(b[i]<0) {//调整异常数据
b[i]+=256;
}
}
//生成png图片
String fileName = UUID.randomUUID().toString().replace("-", "")+".png";
//本地绝对路径
String imgFilePath = path + fileName;
OutputStream out = new FileOutputStream(imgFilePath);
//生成完毕,开始调用压缩方法,删除原图片,保留最后生成的图片
FilePath = PicUtils.commpressPicForScale(imgFilePath, path + destFileName, 20, 0.9);
out.write(b);
out.flush();
out.close();
3,先转换8位,再判断内存大小并进行图片压缩
//在生成图片以后调用,以0.9的比例进行压缩
//FilePath = PicUtils.commpressPicForScale(imgFilePath, path + destFileName, 20, 0.9);
public static String commpressPicForScale(String srcPath, String desPath,long desFileSize, double accuracy) {
if (PubFun.isEmpty(srcPath) || PubFun.isEmpty(srcPath)) {
return null;
}
if (!new File(srcPath).exists()) {
return null;
}
try {
//转换路径,将base64生成的png图片转换成gif图片
convertToEight(srcPath, desPath);
File srcFileJPG = new File(desPath);
long srcFileSizeJPG = srcFileJPG.length();
//判断大小,如果小于20kb,不压缩;如果大于等于20kb,压缩
if (srcFileSizeJPG <= desFileSize * 1024) {
return desPath;
}
commpressPicCycle(desPath, desFileSize, accuracy);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return desPath;
}
private static void commpressPicCycle(String desPath, long desFileSize,double accuracy) throws IOException {
File srcFileJPG = new File(desPath);
long srcFileSizeJPG = srcFileJPG.length();
if (srcFileSizeJPG <= desFileSize * 1024) {
return;
}
Thumbnails.of(desPath).scale(1f).outputQuality(accuracy).toFile(desPath);
commpressPicCycle(desPath, desFileSize, accuracy);
}
/**
* 转换8位(从32位png格式图片转换成8位gif格式图片)
*/
private static void convertToEight(String pngPath, String destination) throws IOException {
//读取png图片路径
ImageIcon ii = new ImageIcon(new File(pngPath).getCanonicalPath());
Image i = ii.getImage();
Image resizedImage = i.getScaledInstance(198, 198, Image.SCALE_SMOOTH);
Image temp = new ImageIcon(resizedImage).getImage();
BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_BGR);
Graphics2D gd = bufferedImage.createGraphics();
bufferedImage = gd.getDeviceConfiguration().createCompatibleImage(198, 198, Transparency.TRANSLUCENT);
gd = bufferedImage.createGraphics();
gd.drawImage(temp, 0, 0, null);
ImageIO.write(bufferedImage, "gif", new File(destination));
}
中间的代码借鉴了很多前辈的关于图片处理的代码,转8位最主要的是read的方式,TYPE_INT_BGR就可以读出8位的,说的不对的还请指正