1. 原生canvas實現(xiàn)用到的API
1) getContext(contextID) ---返回一個用于在畫布上繪圖的環(huán)境
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),然后將剪切的內(nèi)容放到位置為(destX,destY),寬度為(destWidth),高度為(destHeight)的位置上
3) getImageData(x, y, width, height) ---獲取矩形區(qū)域的圖像信息
ctx.getImageData(0, 0, 10, 10) // 獲取左上角坐標為(0, 0),寬高為區(qū)域內(nèi)的圖像信息 // 返回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圖片質(zhì)量,[0, 1]
Canvas.toDataURL("image/png", 1)
2. fabric.js
簡化canvas編寫的庫,為canvas提供所缺少的對象模型
fabric.js能做的事
1)在canvas上創(chuàng)建、填充圖形(包括圖片、文字、規(guī)則圖形和復雜路徑組成圖形)
2)給圖形填充漸變顏色
3)組合圖形(包括組合圖形、圖形文字、圖片等)
4)設置圖形動畫集用戶交互
5)生成JSON, SVG數(shù)據(jù)等
3.使用fabric.js實現(xiàn)用到的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) }) // 監(jiān)聽事件 /* 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() 設置對象內(nèi)容
12)toDataURL(obj)
4.原生canvas實現(xiàn)代碼
<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}, $)`, 2, `rgb(${r}, ${g}, $)`) }, // 添加文字 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) // 清理畫布內(nèi)容 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>
效果圖如下:
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
標簽:紅河 甘南 萍鄉(xiāng) 營口 咸陽 蘇州 文山 惠州
巨人網(wǎng)絡通訊聲明:本文標題《canvas實現(xiàn)圖片馬賽克的示例代碼》,本文關鍵詞 canvas,實現(xiàn),圖片,馬賽克,;如發(fā)現(xiàn)本文內(nèi)容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權與本站無關。上一篇:html5 分層屏幕適配的方法