文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用canvas怎么实现一个图片马赛克效果

2023-06-09 21:52

关注

本篇文章为大家展示了使用canvas怎么实现一个图片马赛克效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

1. 原生canvas实现用到的API

1) getContext(contextID) ---返回一个用于在画布上绘图的环境

Canvas.getContext('2d') // 返回一个 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) // 从原来图片上某一个位置开始(sourceX,sourceY),指定长宽进行剪切(sourceWidth,sourceHeight),然后将剪切的内容放到位置为(destX,destY),宽度为(destWidth),高度为(destHeight)的位置上

使用canvas怎么实现一个图片马赛克效果

3) getImageData(x, y, width, height) ---获取矩形区域的图像信息

ctx.getImageData(0, 0, 10, 10) // 获取左上角坐标为(0, 0),宽高为区域内的图像信息// 返回ImageData: { width: 10, height: 10, data: Uint8ClampedArray[400] }

4)beginPath() ---开始一条路径,或重置当前的路径 5)rect(x, y, width, height) ---绘制矩形

6)lineWidth ---设置或返回当前线条的宽度

7)fillStyle ---设置或返回用于填充绘画的颜色、渐变或模式

ctx.fillStyle = color|gradient|pattern

8)strokeStyle ---设置或返回用于笔触的颜色、渐变或模式

9)globalAlpha ---设置或返回绘图的当前透明值

10)fill() ---填充当前的图像(路径)。默认颜色是黑色

【注】如果路径未关闭,那么 fill() 方法会从路径结束点到开始点之间添加一条线,以关闭该路径,然后填充该路径。

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数据等

使用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)  })// 监听事件

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>

效果图如下:

使用canvas怎么实现一个图片马赛克效果

上述内容就是使用canvas怎么实现一个图片马赛克效果,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯