cropper裁剪图片并上传
程序员文章站
2022-04-09 08:04:36
...
引入cropper所依赖的js和css,可在官网下载。
我的资源地址:https://download.csdn.net/download/rexueqingchun/10593965
把裁剪的图片转化为base64上传
前台程序
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传图片</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/cropper.css">
<link rel="stylesheet" href="css/main.css">
<script src="js/jquery-1.11.3.js"></script>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/cropper.js"></script>
<script type="text/javascript">
$(function () {
var console = window.console || { log: function () {} };
var URL = window.URL || window.webkitURL;
var $image = $('#image');
var $download = $('#download');
var $dataX = $('#dataX');
var $dataY = $('#dataY');
var $dataHeight = $('#dataHeight');
var $dataWidth = $('#dataWidth');
var $dataRotate = $('#dataRotate');
var $dataScaleX = $('#dataScaleX');
var $dataScaleY = $('#dataScaleY');
var options = {
aspectRatio: 1 / 1, //裁剪框的宽高比
viewMode: 1, //视图模式,默认为0:无限制,1:截取框不能移到图片外部,2:不全部铺满背景,3:全部铺满背景
dragMode: 'move',//拖拽模式,默认为crop:产生一个新的裁剪框,可改变大小,move:可移动图片,none:不可移动图片
preview: '.img-preview', //添加额外的元素(容器)以供预览
autoCropArea: 0.5, //定义初始化裁剪框对比图片的比例大小,默认为0.8
cropBoxResizable: true, //是否可以调整剪裁框的大小
cropBoxMovable: true, //是否可以移动剪裁框
crop: function (e) {
$dataX.val(Math.round(e.x));
$dataY.val(Math.round(e.y));
$dataHeight.val(Math.round(e.height));
$dataWidth.val(Math.round(e.width));
$dataRotate.val(e.rotate);
$dataScaleX.val(e.scaleX);
$dataScaleY.val(e.scaleY);
}
};
var originalImageURL = $image.attr('src');
var uploadedImageName = '';
var uploadedImageType = 'image/jpeg';
var uploadedImageURL;
// Cropper
$image.on({
ready: function (e) {
//console.log(e.type);
},
cropstart: function (e) {
//console.log(e.type, e.action);
},
cropmove: function (e) {
//console.log(e.type, e.action);
},
cropend: function (e) {
//console.log(e.type, e.action);
},
crop: function (e) {
//console.log(e.type, e.x, e.y, e.width, e.height, e.rotate, e.scaleX, e.scaleY);
},
zoom: function (e) {
//console.log(e.type, e.ratio);
}
}).cropper(options);
// Buttons
if (!$.isFunction(document.createElement('canvas').getContext)) {
$('button[data-method="getCroppedCanvas"]').prop('disabled', true);
}
if (typeof document.createElement('cropper').style.transition === 'undefined') {
$('button[data-method="rotate"]').prop('disabled', true);
$('button[data-method="scale"]').prop('disabled', true);
}
// Download
if (typeof $download[0].download === 'undefined') {
$download.addClass('disabled');
}
// Methods
$('.docs-buttons').on('click', '[data-method]', function () {
var $this = $(this);
var data = $this.data();
var cropper = $image.data('cropper');
var cropped;
var $target;
var result;
if ($this.prop('disabled') || $this.hasClass('disabled')) {
return;
}
if (cropper && data.method) {
data = $.extend({}, data); // Clone a new one
if (typeof data.target !== 'undefined') {
$target = $(data.target);
if (typeof data.option === 'undefined') {
try {
data.option = JSON.parse($target.val());
} catch (e) {
console.log(e.message);
}
}
}
cropped = cropper.cropped;
switch (data.method) {
case 'rotate': //旋转
if (cropped && options.viewMode > 0) {
$image.cropper('clear');
}
break;
case 'getCroppedCanvas':
if (uploadedImageType === 'image/jpeg') {
if (!data.option) {
data.option = {};
}
data.option.fillColor = '#fff';
}
break;
}
result = $image.cropper(data.method, data.option, data.secondOption);
switch (data.method) {
case 'rotate':
if (cropped && options.viewMode > 0) {
$image.cropper('crop');
}
break;
case 'scaleX':
case 'scaleY':
$(this).data('option', -data.option);
break;
case 'getCroppedCanvas':
if (result) {
// Bootstrap's Modal
$('#getCroppedCanvasModal').modal().find('.modal-body').html(result);
if (!$download.hasClass('disabled')) {
download.download = uploadedImageName;
$download.attr('href', result.toDataURL(uploadedImageType));
}
}
break;
case 'destroy':
if (uploadedImageURL) {
URL.revokeObjectURL(uploadedImageURL);
uploadedImageURL = '';
$image.attr('src', originalImageURL);
}
break;
}
if ($.isPlainObject(result) && $target) {
try {
$target.val(JSON.stringify(result));
} catch (e) {
console.log(e.message);
}
}
}
});
// Import image
var $inputImage = $('#inputImage');
if (URL) {
$inputImage.change(function () {
var files = this.files;
var file;
if (!$image.data('cropper')) {
return;
}
if (files && files.length) {
file = files[0];
if (/^image\/\w+$/.test(file.type)) {
uploadedImageName = file.name;
uploadedImageType = file.type;
if (uploadedImageURL) {
URL.revokeObjectURL(uploadedImageURL);
}
uploadedImageURL = URL.createObjectURL(file);
$image.cropper('destroy').attr('src', uploadedImageURL).cropper(options);
$inputImage.val('');
} else {
window.alert('Please choose an image file.');
}
}
});
} else {
$inputImage.prop('disabled', true).parent().addClass('disabled');
}
//上传图片
$("#getCroppedCanvas").on("click", function () {
var cas = $('#image').cropper('getCroppedCanvas');
if(cas == null){
alert("请选择图片");
return false;
}else{
var base64url = cas.toDataURL('image/jpeg');
$.ajax({
url : 'wap_ajbj_upload_zm.htm',
dataType:'json',
type: "post",
data: {
fileName : uploadedImageName,
imgBase64 : base64url
},
success: function (data) {
if(data.result == 'success'){
alert("上传成功");
}
}
});
}
})
});
</script>
</head>
<body>
<div class="container" style="margin-top: 10px;">
<div class="row">
<div class="col-md-9">
<div class="img-container">
<img id="image" >
</div>
</div>
<div class="col-md-3">
<div class="docs-preview clearfix">
<div class="img-preview preview-lg"></div>
</div>
<div class="docs-data">
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataWidth">宽度</label>
</span>
<input type="text" class="form-control" id="dataWidth" disabled>
<span class="input-group-append">
<span class="input-group-text">像素</span>
</span>
</div>
<div class="input-group input-group-sm">
<span class="input-group-prepend">
<label class="input-group-text" for="dataHeight">高度</label>
</span>
<input type="text" class="form-control" id="dataHeight" disabled>
<span class="input-group-append">
<span class="input-group-text">像素</span>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-9 docs-buttons">
<div class="btn-group">
<button type="button" class="btn btn-primary" data-method="rotate" data-option="-90" title="Rotate Left">
<span class="docs-tooltip" data-animation="false" title="向左旋转">
<span class="fa fa-rotate-left">向左旋转</span>
</span>
</button>
<button type="button" class="btn btn-primary" data-method="rotate" data-option="90" title="Rotate Right">
<span class="docs-tooltip" data-animation="false" title="向右旋转">
<span class="fa fa-rotate-right">向右旋转</span>
</span>
</button>
</div>
<div class="btn-group">
<label class="btn btn-primary btn-upload" for="inputImage" title="Upload image file">
<input type="file" class="sr-only" id="inputImage" name="file" accept="image/*">
<span class="docs-tooltip" data-animation="false" title="打开本地图片">
<span class="fa fa-upload">选择图片</span>
</span>
</label>
</div>
<div class="btn-group btn-group-crop">
<button type="button" class="btn btn-success" data-method="getCroppedCanvas" data-option="{ "maxWidth": 4096, "maxHeight": 4096 }">
<span class="docs-tooltip" data-animation="false" title="获取图片">
获取图片
</span>
</button>
</div>
<!-- 截取固定尺寸 -->
<div class="btn-group btn-group-crop">
<button type="button" class="btn btn-success" data-method="getCroppedCanvas" data-option="{ "width": 200, "height": 200 }">
<span class="docs-tooltip" data-animation="false" title="200*200">
200*200
</span>
</button>
</div>
<div class="btn-group btn-group-crop">
<button id="getCroppedCanvas" type="button" class="btn btn-success" >
<span class="docs-tooltip" data-animation="false" title="上传图片">
上传图片
</span>
</button>
</div>
<!-- 获取图片浮窗 -->
<div class="modal fade docs-cropped" id="getCroppedCanvasModal" aria-hidden="true" aria-labelledby="getCroppedCanvasTitle" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="getCroppedCanvasTitle">图片</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
<a class="btn btn-primary" id="download" href="javascript:void(0);" >下载</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
后台程序
private String filePath = LxwmController.class.getResource("/").getPath().split("WEB-INF")[0]+ "upload/";
@RequestMapping(value = "wap_ajbj_upload_zm.htm", method = {RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public Map<String, Object> wap_ajbj_upload_zm(HttpServletRequest request) throws Exception {
Map<String, Object> result = new HashMap<String, Object>();
String fileName = request.getParameter("fileName");
fileName = System.currentTimeMillis() + "." + fileName.substring(fileName.lastIndexOf(".") + 1);
String imgBase64 = request.getParameter("imgBase64");
imgBase64 = imgBase64.split(",")[1];
GenerateImage(imgBase64,filePath + "/ajbj/zm/"+fileName);
result.put("result", "success");
return result;
}
/**
* @Description: 将base64编码字符串转换为图片
* @param imgStr base64编码字符串
* @param path 图片路径-具体到文件
*/
public static boolean GenerateImage(String imgStr,String imgFilePath){
if (imgStr == null) //图像数据为空
return false;
BASE64Decoder decoder = new BASE64Decoder();
try{
//Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
for(int i=0;i<b.length;++i){
if(b[i] < 0){//调整异常数据
b[i] += 256;
}
}
OutputStream out = new FileOutputStream(imgFilePath);
out.write(b);
out.flush();
out.close();
return true;
}
catch (Exception e){
return false;
}
}
把裁剪的图片转化为blob上传
前台程序
//上传图片js变更为
$("#getCroppedCanvas").on("click", function () {
var cas = $('#image').cropper('getCroppedCanvas');
if(cas == null){
alert("请选择图片");
return false;
}else{
var blob = processData(cas.toDataURL());
var formData = new FormData();
formData.append('croppedImage', blob);
formData.append('fileName', uploadedImageName);
$.ajax({
url : 'wap_ajbj_upload_zm.htm',
type: "post",
data: formData,
processData: false,
contentType: false,
success: function (data) {
if(data.result == 'success'){
alert("上传成功");
}
}
});
}
})
//添加转化为二进制方法
function processData(dataUrl) {
var binaryString = window.atob(dataUrl.split(',')[1]);
var arrayBuffer = new ArrayBuffer(binaryString.length);
var intArray = new Uint8Array(arrayBuffer);
for (var i = 0, j = binaryString.length; i < j; i++) {
intArray[i] = binaryString.charCodeAt(i);
}
var data = [intArray],
blob;
try {
blob = new Blob(data);
} catch (e) {
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder;
if (e.name === 'TypeError' && window.BlobBuilder) {
var builder = new BlobBuilder();
builder.append(arrayBuffer);
blob = builder.getBlob(imgType); // imgType为上传文件类型,即 file.type
} else {
console.log('版本过低,不支持上传图片');
}
}
return blob;
}
后台程序
private String filePath = LxwmController.class.getResource("/").getPath().split("WEB-INF")[0]+ "upload/";
@RequestMapping(value = "wap_ajbj_upload_zm.htm", method = {RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public Map<String, Object> wap_ajbj_upload_zm(@RequestParam(value = "croppedImage",required = false)MultipartFile file, HttpServletRequest request) throws Exception {
Map<String, Object> result = new HashMap<String, Object>();
if(file != null && !file.isEmpty()){
String filename = request.getParameter("fileName"); //获取文件的名字
filename = new String(filename.getBytes("UTF-8"), "UTF-8");
String suffix = filename.substring(filename.lastIndexOf(".") + 1);
filename = System.currentTimeMillis() + "." + suffix;
try {
copyFileRename(file.getInputStream(), filename,filePath + "/ajbj/zm/");
} catch (IOException e) {
e.printStackTrace();
}
}
result.put("result", "success");
return result;
}
public static void copyFileRename(InputStream in, String fileName,String myFilePath) throws IOException {
FileOutputStream fs = new FileOutputStream(myFilePath + fileName);
byte[] buffer = new byte[1024 * 1024];
int byteread = 0;
while ((byteread = in.read(buffer)) != -1) {
fs.write(buffer, 0, byteread);
fs.flush();
}
fs.close();
in.close();
}