前端实现图片裁剪功能,插件版和原生版

概要

最近遇到了一个需要用到图片裁剪功能,自己找了一些资料,有插件版和原生版的,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>

小结

工作好累,想摸鱼。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值