概要
最近遇到了一个需要用到图片裁剪功能,自己找了一些资料,有插件版和原生版的,VUE版本的我就不放了,原理类似,供大家参考。
插件版
Cropper.js 是一个用于裁剪图像的 JavaScript 插件。它可以让用户在浏览器中对图像进行裁剪和编辑操作,具体功能包括但不限于:
1.图像裁剪: 允许用户在预览中选择并裁剪图像的特定区域。
2.缩放和旋转: 支持用户对裁剪区域进行缩放和旋转操作,以便更精确地选择所需部分。
3.上传和导出: 提供了上传和导出裁剪后的图像功能,通常可以导出为Base64格式的图像数据或者Blob对象,以便于上传或保存到服务器。
4.交互式预览: 用户可以在裁剪过程中实时预览裁剪后的效果,可以调整裁剪框的大小和位置。
5.自定义选项: 支持各种自定义选项和配置,例如裁剪框的比例、裁剪框的最小和最大尺寸等,以满足不同场景的需求。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>图片裁剪</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css"
/>
<style>
#image {
max-width: 100%;
}
</style>
</head>
<body>
<h1>图片裁剪</h1>
<input type="file" id="fileInput" accept="image/*" />
<div>
<img id="image" src="" alt="选择图片" />
</div>
<button id="cropButton" style="display: none">裁剪图片</button>
<div>
<img id="croppedImage" src="" alt="裁剪后的图片" />
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>
<script>
document
.getElementById("fileInput")
.addEventListener("change", function (event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function (e) {
const img = document.getElementById("image");
img.src = e.target.result;
img.onload = function () {
const cropper = new Cropper(img, {
aspectRatio: 1 / 1, // 裁剪框的宽高比
viewMode: 1,
dragMode: "move",
autoCropArea: 0.8,
cropBoxMovable: true,
cropBoxResizable: true,
background: true,
});
document.getElementById("cropButton").style.display = "block";
document.getElementById("cropButton").onclick = function () {
const canvas = cropper.getCroppedCanvas();
const base64Image = canvas.toDataURL("image/png");
// 处理裁剪后的图片,例如显示或上传
document.getElementById("croppedImage").src = base64Image;
console.log(base64Image);//输出裁剪后的图片base64编码
};
};
};
reader.readAsDataURL(file);
}
});
</script>
</body>
</html>
JS原生版
原生版的就比较复杂一点,主要是用到了canvas和鼠标的一些事件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片裁剪</title>
<style>
#canvas {
border: 1px solid black;
/* background-color: black; */
}
#croppedImage {
display: none;
}
</style>
</head>
<body>
<input type="file" id="fileInput" accept="image/*">
<canvas id="canvas" width="500" height="500"></canvas>
<button id="cropButton">裁剪</button>
<img id="croppedImage" alt="裁剪后的图片">
<script>
const fileInput = document.getElementById('fileInput');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const cropButton = document.getElementById('cropButton');
const croppedImage = document.getElementById('croppedImage');
let image = new Image();
let cropStartX = 0;
let cropStartY = 0;
let cropEndX = 0;
let cropEndY = 0;
let isDrawing = false;
// 点击上传图片的时候
fileInput.addEventListener('change', function (event) {
const file = event.target.files[0];
const reader = new FileReader();
const maxWidth = 800; // 设置最大宽度
const maxHeight = 600; // 设置最大高度
// 文件读取完成后
reader.onload = function (e) {
const img = new Image();
img.src = e.target.result;
img.onload = function () {
let width = img.width;
let height = img.height;
// 优化:如果图片尺寸超过最大值,进行缩放(防止图片过大溢出屏幕)
if (width > maxWidth || height > maxHeight) {
const ratio = Math.min(maxWidth / width, maxHeight / height);
width *= ratio;
height *= ratio;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
};
};
reader.readAsDataURL(file);
});
// 在图像上鼠标按下的时候
canvas.addEventListener('mousedown', function (event) {
cropStartX = event.offsetX;
cropStartY = event.offsetY;
isDrawing = true;
});
// 在图像上鼠标移动的时候
canvas.addEventListener('mousemove', function (event) {
if (isDrawing) {
console.log('在图像上的时候');
cropEndX = event.offsetX;
cropEndY = event.offsetY;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(image, 0, 0);
ctx.strokeStyle = 'red';
ctx.strokeRect(cropStartX, cropStartY, cropEndX - cropStartX, cropEndY - cropStartY);
}
});
// 在图像上松开鼠标的时候
canvas.addEventListener('mouseup', function (event) {
isDrawing = false;
});
// 点击裁剪的时候
cropButton.addEventListener('click', function () {
// 计算裁剪区域的宽度和高度
const cropWidth = Math.abs(cropEndX - cropStartX);
const cropHeight = Math.abs(cropEndY - cropStartY);
// 计算裁剪区域的左上角坐标
const cropX = Math.min(cropStartX, cropEndX);
const cropY = Math.min(cropStartY, cropEndY);
// 创建canvas 元素,并存放裁剪后的图像
const croppedCanvas = document.createElement('canvas');
croppedCanvas.width = cropWidth;
croppedCanvas.height = cropHeight;
const croppedCtx = croppedCanvas.getContext('2d');
croppedCtx.drawImage(image, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
console.log(croppedCanvas.toDataURL());
croppedImage.src = croppedCanvas.toDataURL();
croppedImage.style.display = 'block';
});
</script>
</body>
</html>
小结
工作好累,想摸鱼。