关于H5调用相机拍照并压缩图片的代码
更新时间:2023-09-15需求背景
在一些移动端的应用场景中,需要用户使用手机的相机拍照并上传图片。因为移动端的屏幕相对较小,用户拍摄的照片可能过大,不仅占用用户的手机存储空间,同时上传和下载也需要更多的时间。因此,需要在拍摄照片时对照片进行压缩,保留图片的主体内容,同时减少照片的大小。
其中,input 标签中的 accept="image/*" 表示只接受用户上传图片类型的文件;capture="camera" 则表示调用相机
调用相机拍照
移动端浏览器需要使用HTML5提供的getUserMedia API来调用摄像头,在调用前需要检查用户设备是否支持这个API。如果设备支持getUserMedia API,拍照逻辑如下所示:
const takePhoto = document.querySelector('#take-photo');
const previewImg = document.querySelector('.preview-img');
takePhoto.addEventListener('change', function() {
const file = takePhoto.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
previewImg.src = e.target.result;
};
});
上述代码中,takePhoto 是调用相机拍摄照片的 input 元素,previewImg 是显示已拍摄照片的 img 元素。当用户拍摄照片后,读取照片文件到 FileReader 中,使用 readAsDataURL方法将照片文件转换为 base64 编码的数据,并将这个数据作为 img 元素的 src 属性值展示给用户
压缩图片
在调用相机拍摄照片后,照片文件的尺寸可能过大,需要对照片进行压缩并将压缩后的数据上传至服务器。在压缩图片时,我们需要先进行尺寸缩放,然后再压缩图片的质量,最后将压缩后的数据上传至服务器。以下是一段压缩图片并上传的代码:
const takePhoto = document.querySelector('#take-photo');
const previewImg = document.querySelector('.preview-img');
const uploadBtn = document.querySelector('.upload-btn');
takePhoto.addEventListener('change', function() {
const file = takePhoto.files[0];
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.src = e.target.result;
img.onload = function() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const scale = img.width / img.height;
const MAX_WIDTH = 600;
const MAX_HEIGHT = MAX_WIDTH / scale;
let width = img.width;
let height = img.height;
if (width > MAX_WIDTH) {
width = MAX_WIDTH;
height = width / scale;
}
if (height > MAX_HEIGHT) {
height = MAX_HEIGHT;
width = height * scale;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
const compressQuality = 0.7;
const compressedDataUrl = canvas.toDataURL('image/jpeg', compressQuality);
previewImg.src = compressedDataUrl;
uploadBtn.onclick = function() {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
alert('上传成功');
}
};
xhr.open('POST', '/upload');
xhr.send(compressedDataUrl);
};
}
};
reader.readAsDataURL(file);
});
上述代码中,通过在 input 元素添加 .capture="camera",读取用户拍照的照片信息,将读取到的照片数据转为图片格式,展示在 img 元素上。然后根据指定的最大宽度,将图片等比例缩放,最后将压缩后的数据上传至服务器。
上传压缩后的照片到服务器
压缩后的照片数据已经在前面部分中实现。在调用压缩方法后,将数据上传至服务器上,使用XMLHttpRequest 的 POST 方法即可上传压缩后的文件。以下是代码实例:
const uploadBtn = document.querySelector('.upload-btn');
uploadBtn.onclick = function() {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
alert('上传成功');
}
};
xhr.open('POST', '/upload');
xhr.send(compressedDataUrl);
};
上述代码中,通过使用 AJAX,异步上传压缩后的照片数据至服务器 /upload的请求中,请求方式使用 POST,当资源上传成功后提醒用户,上传完成。