原生JS实现图片裁剪功能

这篇具有很好参考价值的文章主要介绍了原生JS实现图片裁剪功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

功能介绍:图片通过原生input上传,使用canvas进行图片裁剪。 裁剪框限制不允许超出图片范围,图片限制了最大宽高(自行修改要的尺寸),点击确认获取新的base64图片数据

注:fixed布局不适用该方案,若是fixed布局请查看另一篇文章
效果图:
原生JS实现图片裁剪功能
上代码文章来源地址https://www.toymoban.com/news/detail-507263.html

<!DOCTYPE HTML>
<html>

<head lang="en">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>图片裁剪</title>
</head>

<body>
  <input id="npt" type="file">
  <div id="box">
    <img style="position:absolute;top:0px;left:0px;opacity: 0.3;" src="" id="img1" />
    <img style="position:absolute;top:0px;left:0px;clip: rect(50px, 250px, 250px, 50px);" src="" id="img2" />
    <!--第三层需用绝对定位浮在上面-->
    <div id="dragDiv" style="position: absolute;width: 200px;height: 200px;border: 1px solid #fff;top:50px;left:50px;">
      <div class="Divmin up-left"></div>
      <div class="Divmin up"></div>
      <div class="Divmin up-right"></div>
      <div class="Divmin right"></div>
      <div class="Divmin right-down"></div>
      <div class="Divmin down"></div>
      <div class="Divmin left-down"></div>
      <div class="Divmin left"></div>
      <div class="Divmin-btn" style="right: 68px;background-color: #2d87f5;" id="confirmBtn">确定</div>
      <div class="Divmin-btn" style="right: 0px;background-color: #f5a52d;">取消</div>
    </div>
    <div style="position: absolute; right: 0;">
      <img src="" id="later" alt="">
    </div>

  </div>

</body>

</html>

<style>
  body {}

  #box {
    width: 1200px;
    height: 600px;
    background: #333;
    position: absolute;
    top: 50px;
    left: 50px;
  }

  .Divmin-btn {
    bottom: -40px;
    width: 60px;
    height: 30px;
    line-height: 30px;
    color: white;
    font-size: 12px;
    text-align: center;
    display: inline-block;
    position: absolute;
    border-radius: 3px 3px 3px 3px;
  }

  .Divmin-btn:hover {
    background-color: rgba(60, 103, 222, 0.6);
    color: #efeeee;
  }

  .Divmin-btn:active {
    background-color: rgba(69, 94, 167, 0.6);
    color: #efeeee;
  }

  .Divmin {
    position: absolute;
    width: 8px;
    height: 8px;
    background: #fff;
  }

  .up-left {
    margin-top: -4px;
    margin-left: -4px;
    cursor: nw-resize;
  }

  .up {
    left: 50%;
    /*父元素盒子dragDiv宽度的一半,注意要有绝对定位*/
    margin-left: -4px;
    top: -4px;
    cursor: n-resize;
  }

  .up-right {
    top: -4px;
    right: -4px;
    cursor: ne-resize;
  }

  .right {
    top: 50%;
    margin-top: -4px;
    right: -4px;
    cursor: e-resize;
  }

  .right-down {
    right: -4px;
    bottom: -4px;
    cursor: se-resize;
  }

  .down {
    bottom: -4px;
    left: 50%;
    margin-left: -4px;
    cursor: s-resize;
  }

  .left-down {
    left: -4px;
    bottom: -4px;
    cursor: sw-resize;
  }

  .left {
    left: -4px;
    top: 50%;
    margin-top: -4px;
    cursor: w-resize;
  }

  #img1,
  #img2 {
    max-width: 600px;
    max-height: 300px;
  }
</style>

<script type="text/javascript">
  //禁止图片被选中
  document.onselectstart = new Function('event.returnValue = false;');
  let confirmBtn = document.getElementById('confirmBtn')
  confirmBtn.addEventListener('click', () => {
    drawRect();
  })


  // 获取图片base64数据
  let npt = document.getElementById("npt");
  npt.onchange = function () {
    let reader = new FileReader();
    reader.readAsDataURL(npt.files[0]);
    reader.onloadend = function (e) {
      img1.src = e.target.result;
      img2.src = e.target.result;
      // console.log(e.target.result);// 图片的base64数据
      getImage(e.target.result)
    };
  }

  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext('2d');

  // 创建图片
  let getImage = function (b64) {
    // 创建图片对象
    let image = new Image();
    image.src = `${b64}`;
    image.onload = function () {
      // 获取原图宽高
      let height = img1.offsetHeight;
      let width = img1.offsetWidth;
      //设置canvas大小与原图宽高一致
      canvas.height = height;
      canvas.width = width;
      // 在canvas绘制图片
      ctx.drawImage(this, 0, 0, width, height);
      // 截图:
      // drawRect();

      // 图片上传后设置裁剪框与图片大小一致
      dragDiv.style.height = img1.offsetHeight + 'px'
      dragDiv.style.width = img1.offsetWidth + 'px'
      dragDiv.style.top = 0 + 'px';
      dragDiv.style.left = 0 + 'px';
      setChoice();
    }
  };

  // 绘制截图矩阵
  let drawRect = function () {
    let top = dragDiv.offsetTop;
    let right = dragDiv.offsetLeft + dragDiv.offsetWidth;
    let bottom = dragDiv.offsetTop + dragDiv.offsetHeight;
    let left = dragDiv.offsetLeft;

    // 截图宽度
    let w = right - left;
    // 截图高度
    let h = bottom - top;
    // 获取截图区域内容,截图区域的像素点矩阵
    let cutImage = ctx.getImageData(left, top, w, h);
    // 裁剪后的base64数据
    let newImage = createNewCanvas(cutImage, w, h);
    later.src = newImage;
    // console.log(newImage);// 裁剪后的base64数据
  };

  var createNewCanvas = function (content, width, height) {
    var nCanvas = document.createElement('canvas');
    var nCtx = nCanvas.getContext('2d');
    nCanvas.width = width;
    nCanvas.height = height;
    nCtx.putImageData(content, 0, 0);// 将画布上指定矩形的像素数据,通过 putImageData() 方法将图像数据放回画布
    return nCanvas.toDataURL('image/png');
  }

  //获取id的函数
  function $(id) {
    if (id.indexOf(".") == 0) {
      let className = id.substring(1, id.length);
      let els = document.getElementsByClassName(className);
      return els[0];
    }
    return document.getElementById(id);
  }

  //获取元素相对于屏幕左边及上边的距离,利用offsetLeft
  function getPosition(el) {
    let left = el.offsetLeft;
    let top = el.offsetTop;
    let parent = el.offsetParent;
    while (parent != null) {
      left += parent.offsetLeft;
      top += parent.offsetTop;
      parent = parent.offsetParent;
    }
    return { "left": left, "top": top };
  }

  let dragDiv = $('dragDiv');
  let box = $('box')
  let img1 = $('img1')
  let rightDiv = $('.right');
  let isDraging = false;
  let contact = "";//表示被按下的触点
  //鼠标按下时
  $('.right').onmousedown = function () {
    isDraging = true;
    contact = "right";
  }
  $('.left').onmousedown = function () {
    isDraging = true;
    contact = "left";
  }
  $('.down').onmousedown = function () {
    isDraging = true;
    contact = "down";
  }
  $('.up').onmousedown = function () {
    isDraging = true;
    contact = "up";
  }
  $('.up-right').onmousedown = function () {
    isDraging = true;
    contact = "up-right";
  }
  $('.right-down').onmousedown = function () {
    isDraging = true;
    contact = "down-right";
  }
  $('.up-left').onmousedown = function () {
    isDraging = true;
    contact = "up-left";
  }
  $('.left-down').onmousedown = function () {
    isDraging = true;
    contact = "down-left";
  }

  //鼠标松开时
  window.onmouseup = function () {
    isDraging = false;
  }

  //鼠标移动时
  window.onmousemove = function (e) {
    var e = e || window.event;
    if (isDraging == true) {
      switch (contact) {
        case "up":
          upMove(e);
          break;
        case "right":
          rightMove(e);
          break;
        case "down":
          downMove(e);
          break;
        case "left":
          leftMove(e);
          break;
        case "up-right":
          upMove(e);
          rightMove(e);
          break;
        case "down-right":
          downMove(e);
          rightMove(e);
          break;
        case "down-left":
          downMove(e);
          leftMove(e);
          break;
        case "up-left":
          upMove(e);
          leftMove(e);
          break;
      }
    }
  }

  //up移动
  function upMove(e) {
    let y = e.clientY;//鼠标位置的纵坐标
    let heightBefore = dragDiv.offsetHeight - 2;//选取框变化前的高度
    let addHeight = getPosition(dragDiv).top - y;//增加的高度
    let height = heightBefore + addHeight
    let top = dragDiv.offsetTop - addHeight
    if (top <= 1 || height <= 1) return
    dragDiv.style.height = height + 'px';//选取框变化后的宽度
    dragDiv.style.top = top + 'px';//相当于变化后左上角的纵坐标,鼠标向上移纵坐标减小,下移增大
    setChoice();
  }

  //right移动
  function rightMove(e) {
    let allWidth = img1.offsetWidth + box.offsetLeft
    let x = e.clientX;//鼠标位置的横坐标
    let widthBefore = dragDiv.offsetWidth - 2;//选取框变化前的宽度
    //let widthBefore = dragDiv.clientWidth;
    if (x >= allWidth) return
    let addWidth = x - getPosition(dragDiv).left - widthBefore;//鼠标移动后选取框增加的宽度
    dragDiv.style.width = widthBefore + addWidth + 'px';//选取框变化后的宽度
    setChoice();
  }

  //down移动
  function downMove(e) {
    let heightBefore = dragDiv.offsetHeight - 2;
    let bottom = box.offsetTop + img1.offsetHeight
    let addHeight = e.clientY - getPosition(dragDiv).top - dragDiv.offsetHeight;
    if (e.clientY >= bottom) return
    let height = heightBefore + addHeight
    dragDiv.style.height = heightBefore + addHeight + 'px';
    setChoice();

  }

  //left移动
  function leftMove(e) {
    let widthBefore = dragDiv.offsetWidth - 2;
    let addWidth = getPosition(dragDiv).left - e.clientX;//增加的宽度等于距离屏幕左边的距离减去鼠标位置横坐标
    let width = widthBefore + addWidth
    let left = dragDiv.offsetLeft - addWidth

    if (left <= 1 || width <= 1) return
    dragDiv.style.width = width + 'px';
    dragDiv.style.left = left + 'px';//左边的距离(相当于左边位置横坐标)等于选取框距父级元素的距离减去增加的宽度
    setChoice();
  }

  //设置选取框图片区域明亮显示
  function setChoice() {
    let top = dragDiv.offsetTop;
    let right = dragDiv.offsetLeft + dragDiv.offsetWidth;
    let bottom = dragDiv.offsetTop + dragDiv.offsetHeight;
    let left = dragDiv.offsetLeft;
    $('img2').style.clip = "rect(" + top + "px," + right + "px," + bottom + "px," + left + "px)";
  }
</script>

到了这里,关于原生JS实现图片裁剪功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序---图片裁剪、旋转、预览、上传功能实现(已经封装成组件,需要的到资源下载)

    1、可以拍摄或选择本地图片上传图片数据 2、图片上传数据可以进行裁剪、选择、取消、裁剪后预览、上传以及限制大小,还可以缩放操作,需要的可以解除限制即可 1、点击图片上传按钮时,跳转页面到cropper进行图片选择剪切 wx.navigateTo({       url: `/pages/cropper/cropper?d

    2023年04月26日
    浏览(43)
  • 微信原生实现一个简易的图片上传功能

    wx.showActionSheet():显示操作菜单,选择是从相册选择还是相机拍摄照片 wx.chooseImage():从本地相册选择图片或使用相机拍照。 wx.uploadFile():将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求,其中 content-type 为 multipart/form-data。 wx.previewMedia(): 预览图片和视频。 upload.wx

    2024年02月16日
    浏览(29)
  • fabric.js 组件 图片上传裁剪并进行自定义区域标记

    目录 0. 前言 1. 安装fabric与引入 2. fabric组件的使用 3. 属性相关设置 4. 初始化加载 4. 方法 5. 全代码 利用fabric组件,实现图片上传、图片”裁剪“、自定义的区域标记一系列操作 先放一张效果图吧👇 我用的是全局引入方式,视情况调整  先放一个fabric.js API地址☞Api | Fabric中

    2024年01月22日
    浏览(73)
  • 原生JS:100行js代码带你实现【像素鸟】小游戏(完整代码+素材图片)

    JS:经典小游戏:像素鸟 JS:经典小游戏:贪吃蛇 JS:经典小游戏:扫雷 目录 系列文章目录 像素鸟 1.游戏介绍 2.代码分析 3.代码实现 3.1 随机生成水管 3.2 当水管超过游戏显示区域时,删除这一对水管 3.3 让小鸟不断下降 3.4 通过鼠标点击事件来让小鸟上升 3.5 检测小鸟是否撞

    2024年02月08日
    浏览(36)
  • 微信小程序实现图片多点裁剪

    话不多说,直接上代码 1、页面布局 2、页面样式 3、页面逻辑

    2024年02月13日
    浏览(36)
  • 已实现:JS如何根据视频的http(s)地址,来截取帧图片,并实现大图压缩的功能

    现在,我们已经有了视频的http地址,我们怎么截取帧图片呢?我以Vue为基础架构,来写写代码。 1、先写布局,先得有video,然后得有canvas 界面上很简单,就一个视频容器,一个画布canvas还不让它显示,还有一个就是截取帧图片了。 接下来是js关键方法部分: 以上的代码就是

    2024年01月17日
    浏览(28)
  • 【python脚本】python实现:目标检测裁剪图片样本,根据类标签文件进行裁剪保存

    我在进行目标检测时候,比如红绿灯检测,目标区域很小,样本杂乱。 想要筛选错误样本的话,很困难。可以把目标区域裁剪出来。人大脑处理对于这样的异己比较敏感。样本量较少的话可以自己筛一筛。样本量较大的话,可以训练一个分类模型帮你筛一下。 它就可以实现

    2024年02月15日
    浏览(34)
  • 微信小程序对上传图片进行裁剪实现记录

    媒体 / 图片 / wx.cropImage (qq.com) 小程序图片裁剪插件 image-cropper | 微信开放社区 (qq.com) 1、将插件项目中image-cropper文件内容复制到本地项目中的compoent中 wxml: js:  json: wxss:根据自己需求调整    2、然后在要引用插件的页面json文件中添加image-cropper 3、在引用插件的wxml文件中引

    2024年04月16日
    浏览(37)
  • latex如何对.pdf格式的图片实现裁剪

    目录 问题描述: 问题解决: 在使用draw.io进行绘图,导出的时候不知道为什么周围会有留白,比如下图: 在导入latex的时候,会因为两侧的留白导致整张图片缩小。 如果直接进行裁剪.pdf,可能需要开通会员 不得不感慨latex的强大,可以直接使用命令进行裁剪。 下面是原始的

    2024年02月07日
    浏览(35)
  • aws对象存储s3基于lambda实现图片裁剪

    存储桶名称:wmmzz 1.存储桶策略设置 2. 创建lambda函数 点击跳转到IAM控制台,创建自定义角色,选择服务类型lambda,创建策略 输入策略下一步取名resize-policy,回到创建角色页面,搜索刚才创建的策略选中,再搜索AmazonS3FullAccess选中 点击下一步,输入角色名称resize-role,点击“创建角色

    2024年02月11日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包