前言
做项目时,在移动端,需要实现用户相册图片的上传,并对图片进行缩放裁剪的功能。下面说一下实现流程。
图片上传
HTML5 支持从 input[type=file]
元素中直接获取文件信息,也可以读取文件内容。我们用下面代码就可以实现:
<label for="input" class="btn btn-danger" id="">
<span>选择图片</span>
<input type="file" id="input" class="sr-only">
</label>
读取文件,并生成 Image 元素
这一步就需要用到 FileReader
了,这个类是专门用来读取本地文件的。纯文本或者二进制都可以读取,但是本地文件必须是经过用户允许才能读取,也就是说用户要在input[type=file]
中选择了这个文件,你才能读取到它。
通过 FileReader
我们可以将图片文件转化成 DataURL
,就是以 data:image/png;base64
, 开头的一种URL
,然后可以直接放在 image.src
里,这样本地图片就显示出来了。
<script>
var crop = function () {
var $image = $('#photo');
var $target = $('#result');
$image.cropper('getCroppedCanvas', {
width: 300, // 裁剪后的长宽
height: 300
}).toBlob(function (blob) {
// 裁剪后将图片放到指定标签
$target.attr('src', URL.createObjectURL(blob));
});
}
</script>
Image
就是在 html 里的 <img>
标签,所以可以直接插入到文档流里。
获取裁剪坐标
这一步没啥好说的,实现的方法也很多,这里需要使用缩放功能,所以使用纵横比的方式:
<script>
var options = {
aspectRatio: 1, // 纵横比
viewMode: 2,
preview: '.img-preview' // 预览图的class名
};
</script>
裁剪图片
裁剪图片使用 cropper插件
<script>
var crop = function () {
var $image = $('#photo');
var $target = $('#result');
$image.cropper('getCroppedCanvas', {
width: 300, // 裁剪后的长宽
height: 300
}).toBlob(function (blob) {
// 裁剪后将图片放到指定标签
$target.attr('src', URL.createObjectURL(blob));
});
}
</script>
图片上传
通过ajax 即可上传给后台
完整代码
CSS
<head>
<meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
<title>移动端图片上传</title>
<link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<style>
.row {
margin-bottom: 5px;
}
#photo {
max-width: 100%;
}
.img-preview {
width: 100px;
height: 100px;
overflow: hidden;
}
button {
margin-top: 10px;
}
#result {
width: 150px;
height: 150px;
}
</style>
</head>
Body
<body>
<div class="container">
<div class="row">
<div class="col-sm-12 text-center">
<label for="input" class="btn btn-danger" id="">
<span>选择图片</span>
<input type="file" id="input" class="sr-only">
</label>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-2">
<img src="" id="photo">
</div>
<div class="col-sm-2">
<div>
<p>
预览(100*100):
</p>
<div class="img-preview">
</div>
</div>
<button class="btn btn-primary" onclick="crop()">裁剪图片</button>
<div>
<br/>
<p>
结果:
</p>
<img src="" alt="裁剪结果" id="result">
</div>
</div>
</div>
</div>
</body>
JS
<!-- Scripts -->
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
// 修改自官方demo的js
var initCropper = function (img, input) {
var $image = img;
var options = {
aspectRatio: 1, // 纵横比
viewMode: 2,
preview: '.img-preview' // 预览图的class名
};
$image.cropper(options);
var $inputImage = input;
var uploadedImageURL;
if (URL) {
// 给input添加监听
$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)) {
// 如果URL已存在就先释放
if (uploadedImageURL) {
URL.revokeObjectURL(uploadedImageURL);
}
uploadedImageURL = URL.createObjectURL(file);
// 销毁cropper后更改src属性再重新创建cropper
$image.cropper('destroy').attr('src', uploadedImageURL).cropper(options);
$inputImage.val('');
} else {
window.alert('请选择一个图像文件!');
}
}
});
} else {
$inputImage.prop('disabled', true).addClass('disabled');
}
}
var crop = function () {
var $image = $('#photo');
var $target = $('#result');
$image.cropper('getCroppedCanvas', {
width: 300, // 裁剪后的长宽
height: 300
}).toBlob(function (blob) {
// 裁剪后将图片放到指定标签
$target.attr('src', URL.createObjectURL(blob));
});
}
$(function () {
initCropper($('#photo'), $('#input'));
});
</script>