canvas完成照片马赛克的示例编码

日期:2020-12-12 类型:科技新闻 

关键词:秀米制作h5,h5如何制作,h5小游戏制作,h5游戏开发,免费的h5制作网站

1. 原生态canvas完成用到的API

1) getContext(contextID) ---回到1个用于在画布上制图的自然环境


拷贝编码
编码以下:

Canvas.getContext('2d') // 回到1个 CanvasRenderingContext2D 目标,应用它能够绘图到 Canvas 元素中

2)drawImage

drawImage(imgObj, x, y)  // 按原图尺寸绘图, x、y为照片在画布中的部位座标
drawImage(imgObj, x, y, width, height) // 按特定宽高绘图
drawImage(imgObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight) // 从原先照片上某1个部位刚开始(sourceX,sourceY),特定长宽开展裁切(sourceWidth,sourceHeight),随后将裁切的內容放到部位为(destX,destY),宽度为(destWidth),高宽比为(destHeight)的部位上

3) getImageData(x, y, width, height) ---获得矩形框地区的图象信息内容

ctx.getImageData(0, 0, 10, 10) // 获得左上角座标为(0, 0),宽高为地区内的图象信息内容
// 回到ImageData: { width: 10, height: 10, data: Uint8ClampedArray[400] }

4)beginPath() ---刚开始1条相对路径,或重设当今的相对路径 5)rect(x, y, width, height) ---绘图矩形框

6)lineWidth ---设定或回到当今线条的宽度

7)fillStyle ---设定或回到用于填充美术绘画的色调、渐变色或方式

ctx.fillStyle = color|gradient|pattern

8)strokeStyle ---设定或回到用于笔触的色调、渐变色或方式

9)globalAlpha ---设定或回到制图确当前全透明值

10)fill() ---填当做前的图象(相对路径)。默认设置色调是黑色

【注】假如相对路径未关掉,那末 fill() 方式会从相对路径完毕点到刚开始点之间加上1条线,以关掉该相对路径,随后填充该相对路径。

11)stroke() ---会具体地绘图出根据 moveTo() 和 lineTo() 方式界定的相对路径。默认设置色调是黑色

12)toDataURL(type, encoderOptions) ---导出来照片,type为照片种类, encoderOptions照片品质,[0, 1]

Canvas.toDataURL("image/png", 1)

2. fabric.js

简化canvas撰写的库,为canvas出示所缺乏的目标实体模型

fabric.js能做的事

1)在canvas上建立、填充图型(包含照片、文本、标准图型和繁杂相对路径构成图型)

2)给图型填充渐变色色调

3)组成图型(包含组成图型、图型文本、照片等)

4)设定图型动漫集客户互动

5)转化成JSON, SVG数据信息等

3.应用fabric.js完成用到的API

1)申明画布

let canvas =new fabric.Canvas('canvas') {
   width: 200,
   height: 200
}

插进照片

let imgInstance = new fabric.Image(imgElement,{
  left: 0,
  top: 0,
  width: 100,
  height: 100,
  angle: 0
}

3)设定情况照片 setBackgroundImage

canvas.setBackgroundImage(imgInstance)

4)renderAll() 再次绘图

5)on() 客户互动

canvas.on('mouse:down', function(options) {  
   console.log(options.e.clientX, options.e.clientY)  
})

// 监视恶性事件
/* 
   mouse:down :电脑鼠标按下时
   mouse:move :电脑鼠标挪动时
   mouse:up :电脑鼠标抬起时
   after:render :画布重绘后
   object:selected:目标被选定
   object:moving:目标挪动
   object:rotating:目标被转动
   object:added:目标被添加
   object:removed目标被移除 
*/

6)getPointer()

7)setWidth()、setHeight() 设定canvas的宽高

8)画矩形框

let rect = new fabric.Rect({
 left: 0,
 top: 0,
 width: 100,
 height: 100
})

add(obj) 加上图型

canvas.add(rect)

10)remove(obj) 移除图型

11)set() 设定目标內容

12)toDataURL(obj)

4.原生态canvas完成编码

<template>
<div class="container">
  <div class="operations">
    <ul>
      <li @click="mosaic">马赛克</li>
      <li @click="addText">加上文本</li>
      <li @click="tailor">剪裁</li>
      <li @click="rotate">转动</li>
      <li @click="exportImg">导出来照片</li>
    </ul>
  </div>
  <canvas ref="imgContent" class="img-wrap">
    你的访问器太low🌶
  </canvas>
</div>
</template>

<script>
  export default {
    data () {
      return {
        context: '',
        canvas: '',
        isMasic: false,
        isText: false,
        isTailor: false,
        isTranslate: false,
        squareEdgeLength: 20,
        angle: 0,
        img: ''
      }
    },
    mounted () {
      this.initData()
    },
    methods: {
      initData () {
        let imgContent = this.$refs.imgContent
        this.canvas = imgContent
        this.context = imgContent.getContext('2d')
        let  Img = new Image()
        this.image = Img
        Img.crossOrigin = "Anonymous"
        Img.src = 'http://oia85104s.bkt.clouddn.com/PictureUnlock_193139.pictureunlock.jpg'
        this.canvas.setAttribute('width', Img.width)
        this.canvas.setAttribute('height', Img.height)
        let self = this
        Img.onload = () => {
          let beginX, beginY, endX, endY
          self.context.drawImage(Img, 0, 0)
          self.context.save()

          self.canvas.addEventListener('mousedown', e => {
            beginX = e.offsetX
            beginY = e.offsetY
            self.canvas.addEventListener('mouseup', e => {
              endX = e.offsetX
              endY = e.offsetY
              if (self.isMasic) {
                self.makeGrid(beginX, beginY, endX - beginX, endY - beginY)
                return
              }
              if (self.isTailor) {
                self.context.drawImage(Img, beginX, beginY, endX - beginX, endY - beginY, 0, 0, endX - beginX, endY - beginY)
                return
              }
            })
          })
        }
      },
      drawRect  (x, y, width, height, fillStyle, lineWidth, strokeStyle, globalAlpha) {
        this.context.beginPath()
        this.context.rect(x, y, width, height)
        this.context.lineWidth = lineWidth
        this.context.strokeStyle = strokeStyle
        fillStyle && (this.context.fillStyle = fillStyle)
        globalAlpha && (this.context.globalAlpha = globalAlpha)

        this.context.fill()
        this.context.stroke()
      },
      // 打马赛克
      mosaic () {
        let self = this
        this.resetClickStatus()
        this.isMasic = true
      },
      makeGrid (beginX, beginY, rectWidth, rectHight) {
        const row = Math.round(rectWidth / this.squareEdgeLength) + 1
        const column = Math.round(rectHight / this.squareEdgeLength) + 1
        for (let i = 0; i < row * column; i++) {
          let x = (i % row) * this.squareEdgeLength + beginX
          let y = parseInt(i / row) * this.squareEdgeLength + beginY
          this.setColor(x, y)
        }
      },
      setColor (x, y) {
        const imgData = this.context.getImageData(x, y, this.squareEdgeLength, this.squareEdgeLength).data
        let r = 0, g = 0, b = 0
        console.log(this.context.getImageData(x, y, this.squareEdgeLength, this.squareEdgeLength), JSON.stringify(imgData))
        for (let i = 0; i < imgData.length; i += 4) {
          r += imgData[i]
          g += imgData[i + 1]
          b += imgData[i + 2]
        }
        r = Math.round(r / (imgData.length / 4))
        g = Math.round(g / (imgData.length / 4))
        b = Math.round(b / (imgData.length / 4))
        this.drawRect(x, y, this.squareEdgeLength, this.squareEdgeLength, `rgb(${r}, ${g}, ${b})`, 2, `rgb(${r}, ${g}, ${b})`)
      },
      // 加上文本
      addText () {
        this.resetClickStatus()
        this.isText = true
        console.log('加上文本')
      },
      // 剪裁
      tailor () {
        this.resetClickStatus()
        this.isTailor = true
        console.log('剪裁')
      } ,
      // 转动
      rotate () {
        // if (this.angle === 360) {
        //   this.angle = 90
        // } else {
        //   this.angle += 90
        // }
        // if ([90, 270].includes(this.angle)) {
        //   this.canvas.setAttribute('width', this.image.height)
        //   this.canvas.setAttribute('height', this.image.width)
        // } else {
        //   this.canvas.setAttribute('width', this.image.width)
        //   this.canvas.setAttribute('height', this.image.height)
        // }
        const x = this.image.width / 2
        const y = this.image.height / 2
        this.context.clearRect(0,0, this.canvas.width, this.canvas.height)  // 清除画布內容
        this.context.translate(x, y)
        this.context.rotate(90 * Math.PI / 180)
        this.context.translate(-x, -y)
        this.context.drawImage(this.image, 0, 0)
      },
      resetClickStatus () {
        this.isMasic = false
        this.isText = false
        this.isTailor = false
        this.isTranslate = false
      },
      exportImg () {
        this.resetClickStatus()
        const exportUrl = this.canvas.toDataURL("image/jpeg")
        let a = document.createElement('a')
        a.setAttribute('download', '')
        a.href = exportUrl
        document.body.appendChild(a)
        a.click()
      }
    }
  }
</script>

<style scoped lang="less">
.operations {
  width: 1200px;
  margin: 0 auto;
  ul {
    display: flex;
    align-items: center;
    margin-bottom: 30px;
    li {
      list-style: none;
      margin-right: 20px;
      cursor: pointer;
    }
  }
}
.img-wrap {
  display: block;
  margin: 0 auto;
}
</style>

实际效果图以下:

以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。