canvas实现图片旋转并保存

html部分

<body>
  <div class="container">
    <div class="source">

      <img id="nc" src="./assets/btbg.jpg" alt="" srcset="">
      <!-- <img id="nc" src="./assets/奶茶.webp" alt="" srcset=""> -->
    </div>
    <div class="cc">
      <canvas class="copy" width="1080" height="1920"></canvas>
    </div>
    <div class="rc">
      <canvas class="rotate" width="1080" height="1920"></canvas>
    </div>

  </div>
</body>

style部分

由于只是一个测试的demo,这部分写的比较随意,选择器记得给名字

<style>
  html,
  body {
    height: 100%;
    width: 100%;
    margin: 0;
    box-sizing: border-box;
    font-family: Helvetica;
  }

  .container {
    width: 100%;
    height: 100%;
    display: flex;
  }

  .container>div {
    width: 33%;
    min-width: 360px;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 10px;
  }

  div>canvas {
    display: flex;
    justify-content: center;
    width: 100%;
    height: auto;
  }

  div>img {
    max-width: 100%;
    max-height: 100%;
    height: auto;
    width: auto;
  }
</style>

js部分

  const c1 = document.querySelector('.copy')
  const c2 = document.querySelector('.rotate')
  const c1c = document.querySelector('.cc')
  const c2c = document.querySelector('.rc')
  const ctx1 = c1.getContext('2d')
  const ctx2 = c2.getContext('2d')
  const img = document.querySelector('#nc')
  img.onload = res => {
    // 图片宽高
    let iw = img.width
    let ih = img.height
    // canvas宽高
    let cw = c1.width
    let ch = c1.height

    let { rw, rh, points } = getXY(cw, ch, iw, ih)

    ctx1.drawImage(img, points[0], points[1], rw, rh)
    // 见图1
    const opt = getXY(cw, cw, ih, iw)
    console.log(opt);
    ctx2.translate(0, opt.rh + opt.points[1])
    ctx2.rotate(-Math.PI / 2)
    ctx2.drawImage(img, opt.points[1], opt.points[0], opt.rh, opt.rw)
    ctx2.translate(0, -(opt.rh + opt.points[1]))
    ctx2.rotate(Math.PI / 2)
    // 将有效部分图片截取
    let frame = ctx2.getImageData(0, 0, opt.rw, opt.rh)
    // 将canvas保持与图片大小相同
    c2.height = opt.rh
    // 清除画布
    ctx2.clearRect(0,0,opt.rw,opt.rh)
    // 重新绘制
    ctx2.putImageData(frame, 0, 0)
  }

保存的方法网上有很多,这是抄得一段

function saveAsImage(canvas) {
    var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); // here is the most important part because if you dont replace you will get a DOM 18 exception.

    //save as download without name and extension
    //window.location.href = image; 
	// 这里需要一个id为link的a标签,用createElement也行
    var link = document.getElementById('link');
    link.setAttribute('download', 'my.png');
    link.setAttribute('href', canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"));
    link.click();
}

图1

请添加图片描述

简单说下,旋转90度后,由第四象限位移到第一象限,我这里canvas比例大概为3/5,高比宽大,于是最大高度变为宽度,能显示的部分就上图那么大

计算位置函数

/**
   * @description: 
   * @param {*} cw canvas宽度
   * @param {*} ch canvas高度
   * @param {*} iw img宽度
   * @param {*} ih img高度
   * @return {*}
   */
  function getXY(cw, ch, iw, ih) {
    // 比较宽高比例,大的一边撑满
    let icw = iw / cw
    let ich = ih / ch
    let li = iw / ih
    let lc = cw / ch
    console.log('图片宽高比', li, 'canvas宽高比', lc);
    // 需要绘制的宽高起点
    let points = [0, 0]
    let rw, rh
    let wall = false // 是否宽度占满
    if (li > lc) {
      // 宽度100%,等比缩放
      rw = cw
      rh = rw / li
      points[0] = 0
      points[1] = (ch - rh) / 2
      wall = true
    } else {
      rh = ch
      rw = rh * li
      points[0] = (cw - rw) / 2
      points[1] = 0
      wall = false
    }
    rw = Math.floor(rw)
    rh = Math.floor(rh)
    console.log('canvas', cw, ch, 'img', iw, ih, '绘制', rw, rh);
    return {
      points,
      rw,
      rh
    }
  }

效果图

请添加图片描述
左边是原图,第二张是canvas绘制原图,第三张是canvas旋转90度之后的图

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值