canvas基础4 -- 图像

drawImage

context.drawImage(image, dx, dy)

dx, dy:图片左上角起始值

图片大小默认为图片原有的尺寸

图片超出canvas的部分会自动裁剪掉

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">
        您的浏览器尚不支持canvas
    </canvas>

    <script>
        const canvas = document.getElementById("canvas")
        const context = canvas.getContext("2d")
        const image = new Image()

        window.onload = function(){

            canvas.width = 1200
            canvas.height = 800

            image.src = "img.jpg"
            image.onload = function(){
                context.drawImage( image , 0 , 0 )
            }

        }

    </script>
</body>
</html>

图示:

context.drawImage(image, dx, dy, dw, dh)

dw,dh: 设置绘制图片的宽和高

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">
        您的浏览器尚不支持canvas
    </canvas>

    <script>
        const canvas = document.getElementById("canvas")
        const context = canvas.getContext("2d")
        const image = new Image()

        window.onload = function(){

            canvas.width = 1200
            canvas.height = 800

            image.src = "img.jpg"
            image.onload = function(){
                context.drawImage( image , 0 , 0,  canvas.width, canvas.height )
            }

        }

    </script>
</body>
</html>

图示:

context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

sx, sy, sw, sh:设置渲染原图像的 起始点和宽高

示例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">
        您的浏览器尚不支持canvas
    </canvas>

    <script>
        const canvas = document.getElementById("canvas")
        const context = canvas.getContext("2d")
        const image = new Image()

        window.onload = function(){

            canvas.width = 1200
            canvas.height = 800

            image.src = "img.jpg"
            image.onload = function(){
                context.drawImage(image , 600, 200, 400, 400, 200 , 200, 400, 400)
            }

        }

    </script>
</body>
</html>

图示:

缩放图像

示例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">
        您的浏览器尚不支持canvas
    </canvas>
    <input type="range" id="scale-range" min="0.5" max="3.0" step="0.01" value="1.0" style="display:block;margin:20px auto;width:800px;" />

    <script>
        const canvas = document.getElementById("canvas")
        const context = canvas.getContext("2d")
        const slider = document.getElementById('scale-range')
        const image = new Image()

        window.onload = function(){

            canvas.width = 1152
            canvas.height = 768

            let scale = slider.value

            image.src = "img-lg.jpg"
            image.onload = function(){
                drawImageByScale(scale)
                slider.onmousemove = function() {
                    scale = slider.value
                    drawImageByScale(scale)
                }
            }
        }

        function drawImageByScale(scale) {
            const imageWidth = 1152 * scale
            const imageHeight = 768 * scale
            const dx = canvas.width / 2 - imageWidth / 2
            const dy = canvas.height / 2 - imageHeight / 2
            context.clearRect(0, 0, canvas.width, canvas.height)
            context.drawImage(image, dx, dy, imageWidth, imageHeight)
        }

    </script>
</body>
</html>

图示:

添加水印

制作第二个canvas用于做水印,并加载到第一个canvas上

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">
        您的浏览器尚不支持canvas
    </canvas>
    <input type="range" id="scale-range" min="0.5" max="3.0" step="0.01" value="1.0" style="display:block;margin:20px auto;width:800px;" />

    <canvas id="watermark-canvas" style="display:none;margin:0 auto;border:1px solid #aaa;">
        您的浏览器尚不支持canvas
    </canvas>

    <script>
        const canvas = document.getElementById("canvas")
        const context = canvas.getContext("2d")
        const slider = document.getElementById('scale-range')
        const image = new Image()

        const watermarkCanvas = document.getElementById("watermark-canvas")
        const watermarkContext = watermarkCanvas.getContext("2d")

        window.onload = function(){

            canvas.width = 1152
            canvas.height = 768

            let scale = slider.value

            image.src = "img-lg.jpg"
            image.onload = function(){
                drawImageByScale(scale)
                slider.onmousemove = function() {
                    scale = slider.value
                    drawImageByScale(scale)
                }
            }

            // setup watermark canvas
            watermarkCanvas.width = 600
            watermarkCanvas.height = 100
            watermarkContext.font = 'bold 50px Arial'
            watermarkContext.fillStyle = 'rgba(255, 255, 255, 0.5)'
            watermarkContext.textBaseline = 'middle'
            watermarkContext.fillText('== liuyubobobo.com ==', 20, 50)
        }

        function drawImageByScale(scale) {
            const imageWidth = 1152 * scale
            const imageHeight = 768 * scale
            const dx = canvas.width / 2 - imageWidth / 2
            const dy = canvas.height / 2 - imageHeight / 2
            context.clearRect(0, 0, canvas.width, canvas.height)
            context.drawImage(image, dx, dy, imageWidth, imageHeight)
            context.drawImage(watermarkCanvas, canvas.width - watermarkCanvas.width, canvas.height - watermarkCanvas.height)
        }

    </script>
</body>
</html>

图示:

放大镜

示例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">
        您的浏览器尚不支持canvas
    </canvas>

    <canvas id="offCanvas" style="display:none;"></canvas>

    <script>
        const canvas = document.getElementById("canvas")
        const context = canvas.getContext("2d")

        const offCanvas = document.getElementById("offCanvas")
        const offContext = offCanvas.getContext("2d")

        const image = new Image()
        let isMouseDown = false
        let scale

        window.onload = function(){

            canvas.width = 1152
            canvas.height = 768

            image.src = "img-lg.jpg"
            image.onload = function(){
                offCanvas.width = image.width
                offCanvas.height = image.height
                scale = offCanvas.width / canvas.width

                context.drawImage(image, 0, 0, canvas.width, canvas.height)
                offContext.drawImage(image, 0, 0)
            }
        }

        function windowToCanvas(x, y) {
            const bbox = canvas.getBoundingClientRect()
            return {
                x: x - bbox.left,
                y: y - bbox.top,
            }
        }

        canvas.onmousedown = function(e) {
            e.preventDefault()
            const point = windowToCanvas(e.clientX, e.clientY)
            isMouseDown = true
            drawCanvasWithMagnifier(point)
        }

        canvas.onmousemove = function(e) {
            e.preventDefault()
            if (isMouseDown) {
                const point = windowToCanvas(e.clientX, e.clientY)
                drawCanvasWithMagnifier(point)
            }
        }

        canvas.onmouseup = function (e) {
            e.preventDefault()
            isMouseDown = false
            drawCanvasWithMagnifier()
        }

        canvas.onmouseout = function (e) {
            e.preventDefault()
            isMouseDown = false
            drawCanvasWithMagnifier()
        }

        function drawCanvasWithMagnifier(point) {
            context.clearRect(0, 0, canvas.width, canvas.height)
            context.drawImage(image, 0, 0, canvas.width, canvas.height)
            if (isMouseDown) {
                drawMagnifier(point)
            }
        }

        function drawMagnifier(point) {
            // 计算放大镜的中心点坐标
            const imageLG_cx = point.x * scale
            const imageLG_cy = point.y * scale

            // 放大镜的半径
            const mr = 200
            
            // 在大图上开始截取的左上角坐标
            const sx = imageLG_cx - mr
            const sy = imageLG_cy - mr

            // 放大镜绘制的左上角坐标
            const dx = point.x - mr
            const dy = point.y - mr

            context.save()
            context.lineWidth = 10
            context.strokeStyle = '#069'

            context.beginPath()
            context.arc(point.x, point.y, mr, 0, Math.PI*2)
            context.stroke()
            
            context.clip()

            context.drawImage(offCanvas, sx, sy, mr*2, mr*2, dx, dy, mr*2, mr*2)

            context.restore()
        }
    </script>
</body>
</html>

图示:

获取图像像素

getImageData

imageDate = context.getImageData(x, y, w, h)

ImageData对象

width

height

data

putImageData

示例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <div style="margin: 10px auto; width:1700px;">
        <canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;">
        </canvas>

        <canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;">
        </canvas>
    </div>
    <div style="clear: both"></div>

    <div style="text-align: center; margin-top:10px;font-size:20px;">
        <a href = "javascript:filter()" >Filter</a>
    </div>
    <script>
        var canvasa = document.getElementById("canvasa")
        var contexta = canvasa.getContext("2d")

        var canvasb = document.getElementById("canvasb")
        var contextb = canvasb.getContext("2d")

        var image = new Image()

        window.onload = function(){

            image.src = "autumn.jpg"
            image.onload = function(){
                contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
            }
        }

        function filter() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            contextb.putImageData(imageData, 0, 0, 50, 50, canvasb.width-100, canvasb.height-100)
        }
    </script>
</body>
</html>

图示:

ImageData.data

示例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <div style="margin: 10px auto; width:1700px;">
        <canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;">
        </canvas>

        <canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;">
        </canvas>
    </div>
    <div style="clear: both"></div>

    <div style="text-align: center; margin-top:10px;font-size:20px;">
        <a href = "javascript:filter()" >Filter</a>
    </div>
    <script>
        var canvasa = document.getElementById("canvasa")
        var contexta = canvasa.getContext("2d")

        var canvasb = document.getElementById("canvasb")
        var contextb = canvasb.getContext("2d")

        var image = new Image()

        window.onload = function(){

            image.src = "autumn.jpg"
            image.onload = function(){
                contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
            }
        }

        function filter() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for(let i = 0; i < canvasb.width * canvasb.height; i++) {
                pixelData[4 * i + 0] = 0
            }

            contextb.putImageData(imageData, 0, 0, 50, 50, canvasb.width-100, canvasb.height-100)
        }
    </script>
</body>
</html>

图示:

createImageData

imageDate = context.createImageData(w, h)

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <canvas id="canvas" style="display:block;margin:0 auto;border:1px solid #aaa;">
        您的浏览器尚不支持canvas
    </canvas>

    <script>
        var canvas = document.getElementById("canvas")
        var context = canvas.getContext("2d")

        window.onload = function(){

            canvas.width = 800
            canvas.height = 800

            var imageData = context.createImageData( canvas.width , canvas.height )
            var pixelData = imageData.data

            for( var i = 0 ; i < canvas.height ; i ++ )
                for( var j = 0 ; j < canvas.width ; j ++ ){

                    var p = i*canvas.width+j

                    pixelData[4*p+0] = parseInt(Math.pow(Math.cos(Math.atan2(j-400,i-400)/2),2)*255)
                    pixelData[4*p+1] = parseInt(Math.pow(Math.cos(Math.atan2(j-400,i-400)/2-2*Math.acos(-1)/3),2)*255)
                    pixelData[4*p+2] = parseInt(Math.pow(Math.cos(Math.atan2(j-400,i-400)/2+2*Math.acos(-1)/3),2)*255)
                    pixelData[4*p+3] = 255
                }

            context.putImageData( imageData , 0 , 0 , 0 , 0 , canvas.width , canvas.height )
        }
    </script>
</body>
</html>

图示:

滤镜

灰度滤镜

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <div style="margin: 10px auto; width:1700px;">
        <canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;">
        </canvas>

        <canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;">
        </canvas>
    </div>
    <div style="clear: both"></div>

    <div style="text-align: center; margin-top:10px;font-size:20px;">
        <a href = "javascript:greyEffect()" >灰度滤镜</a>
    </div>
    <script>
        var canvasa = document.getElementById("canvasa")
        var contexta = canvasa.getContext("2d")

        var canvasb = document.getElementById("canvasb")
        var contextb = canvasb.getContext("2d")

        var image = new Image()

        window.onload = function(){

            image.src = "autumn.jpg"
            image.onload = function(){
                contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
            }
        }

        function greyEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for(let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r*0.3 + g*0.59 + b*0.11

                pixelData[4 * i + 0] = grey
                pixelData[4 * i + 1] = grey
                pixelData[4 * i + 2] = grey
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }
    </script>
</body>
</html>

图示:

黑白滤镜

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <div style="margin: 10px auto; width:1700px;">
        <canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;">
        </canvas>

        <canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;">
        </canvas>
    </div>
    <div style="clear: both"></div>

    <div style="text-align: center; margin-top:10px;font-size:20px;">
        <a href="javascript:greyEffect()">灰度滤镜</a>
        <a href="javascript:blackEffect()">黑白滤镜</a>
    </div>
    <script>
        var canvasa = document.getElementById("canvasa")
        var contexta = canvasa.getContext("2d")

        var canvasb = document.getElementById("canvasb")
        var contextb = canvasb.getContext("2d")

        var image = new Image()

        window.onload = function(){

            image.src = "autumn.jpg"
            image.onload = function(){
                contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
            }
        }

        function greyEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for(let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r*0.3 + g*0.59 + b*0.11

                pixelData[4 * i + 0] = grey
                pixelData[4 * i + 1] = grey
                pixelData[4 * i + 2] = grey
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function blackEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for (let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r * 0.3 + g * 0.59 + b * 0.11
                let v
                if (grey > 255/2) {
                    v = 255
                } else {
                    v = 0
                }

                pixelData[4 * i + 0] = v
                pixelData[4 * i + 1] = v
                pixelData[4 * i + 2] = v
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }
    </script>
</body>
</html>

图示:

反色滤镜

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <div style="margin: 10px auto; width:1700px;">
        <canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;">
        </canvas>

        <canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;">
        </canvas>
    </div>
    <div style="clear: both"></div>

    <div style="text-align: center; margin-top:10px;font-size:20px;">
        <a href="javascript:greyEffect()">灰度滤镜</a>
        <a href="javascript:blackEffect()">黑白滤镜</a>
        <a href="javascript:reverseEffect()">反色滤镜</a>
    </div>
    <script>
        var canvasa = document.getElementById("canvasa")
        var contexta = canvasa.getContext("2d")

        var canvasb = document.getElementById("canvasb")
        var contextb = canvasb.getContext("2d")

        var image = new Image()

        window.onload = function(){

            image.src = "autumn.jpg"
            image.onload = function(){
                contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
            }
        }

        function greyEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for(let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r*0.3 + g*0.59 + b*0.11

                pixelData[4 * i + 0] = grey
                pixelData[4 * i + 1] = grey
                pixelData[4 * i + 2] = grey
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function blackEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for (let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r * 0.3 + g * 0.59 + b * 0.11
                let v
                if (grey > 255/2) {
                    v = 255
                } else {
                    v = 0
                }

                pixelData[4 * i + 0] = v
                pixelData[4 * i + 1] = v
                pixelData[4 * i + 2] = v
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function reverseEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for (let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                pixelData[4 * i + 0] = 255 - r
                pixelData[4 * i + 1] = 255 - g
                pixelData[4 * i + 2] = 255 - b
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }
    </script>
</body>
</html>

图示:

模糊滤镜

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <div style="margin: 10px auto; width:1700px;">
        <canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;">
        </canvas>

        <canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;">
        </canvas>
    </div>
    <div style="clear: both"></div>

    <div style="text-align: center; margin-top:10px;font-size:20px;">
        <a href="javascript:greyEffect()">灰度滤镜</a>
        <a href="javascript:blackEffect()">黑白滤镜</a>
        <a href="javascript:reverseEffect()">反色滤镜</a>
        <a href="javascript:blurEffect()">模糊滤镜</a>
    </div>
    <script>
        var canvasa = document.getElementById("canvasa")
        var contexta = canvasa.getContext("2d")

        var canvasb = document.getElementById("canvasb")
        var contextb = canvasb.getContext("2d")

        var image = new Image()

        window.onload = function(){

            image.src = "autumn.jpg"
            image.onload = function(){
                contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
            }
        }

        function greyEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for(let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r*0.3 + g*0.59 + b*0.11

                pixelData[4 * i + 0] = grey
                pixelData[4 * i + 1] = grey
                pixelData[4 * i + 2] = grey
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function blackEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for (let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r * 0.3 + g * 0.59 + b * 0.11
                let v
                if (grey > 255/2) {
                    v = 255
                } else {
                    v = 0
                }

                pixelData[4 * i + 0] = v
                pixelData[4 * i + 1] = v
                pixelData[4 * i + 2] = v
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function reverseEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for (let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                pixelData[4 * i + 0] = 255 - r
                pixelData[4 * i + 1] = 255 - g
                pixelData[4 * i + 2] = 255 - b
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function blurEffect() {
            const tmpImageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const tmpPixelData = tmpImageData.data

            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            const blurR = 3 // 控制模糊程度

            for (let i = blurR; i < canvasb.height - blurR; i++) {
                for (let j = blurR; j < canvasb.width - blurR; j++) {
                    let totalr = 0
                    let totalg = 0
                    let totalb = 0
                    for (let dx = -blurR; dx <= blurR; dx++) {
                        for (let dy = -blurR; dy <= blurR; dy++) {
                            const x = i + dx
                            const y = j + dy

                            const p = x * canvasb.width + y
                            totalr += tmpPixelData[p*4 + 0]
                            totalg += tmpPixelData[p*4 + 1]
                            totalb += tmpPixelData[p*4 + 2]
                        }
                    }
                    const p = i * canvasb.width + j
                    const totalNum = (2*blurR + 1)* (2*blurR + 1)
                    pixelData[p * 4 + 0] = totalr / totalNum
                    pixelData[p * 4 + 1] = totalg / totalNum
                    pixelData[p * 4 + 2] = totalb / totalNum
                }
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }
    </script>
</body>
</html>

图示:

马赛克滤镜

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <div style="margin: 10px auto; width:1700px;">
        <canvas id="canvasa" width="800" height="560" style="display:block;float:left;border:1px solid #aaa;">
        </canvas>

        <canvas id="canvasb" width="800" height="560" style="display:block;float:right;border:1px solid #aaa;">
        </canvas>
    </div>
    <div style="clear: both"></div>

    <div style="text-align: center; margin-top:10px;font-size:20px;">
        <a href="javascript:greyEffect()">灰度滤镜</a>
        <a href="javascript:blackEffect()">黑白滤镜</a>
        <a href="javascript:reverseEffect()">反色滤镜</a>
        <a href="javascript:blurEffect()">模糊滤镜</a>
        <a href="javascript:mosaicEffect()">马赛克滤镜</a>
    </div>
    <script>
        var canvasa = document.getElementById("canvasa")
        var contexta = canvasa.getContext("2d")

        var canvasb = document.getElementById("canvasb")
        var contextb = canvasb.getContext("2d")

        var image = new Image()

        window.onload = function(){

            image.src = "autumn.jpg"
            image.onload = function(){
                contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height )
            }
        }

        function greyEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for(let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r*0.3 + g*0.59 + b*0.11

                pixelData[4 * i + 0] = grey
                pixelData[4 * i + 1] = grey
                pixelData[4 * i + 2] = grey
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function blackEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for (let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                const grey = r * 0.3 + g * 0.59 + b * 0.11
                let v
                if (grey > 255/2) {
                    v = 255
                } else {
                    v = 0
                }

                pixelData[4 * i + 0] = v
                pixelData[4 * i + 1] = v
                pixelData[4 * i + 2] = v
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function reverseEffect() {
            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            for (let i = 0; i < canvasb.width * canvasb.height; i++) {
                const r = pixelData[4 * i + 0]
                const g = pixelData[4 * i + 1]
                const b = pixelData[4 * i + 2]

                pixelData[4 * i + 0] = 255 - r
                pixelData[4 * i + 1] = 255 - g
                pixelData[4 * i + 2] = 255 - b
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function blurEffect() {
            const tmpImageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const tmpPixelData = tmpImageData.data

            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            const blurR = 3 // 控制模糊程度

            for (let i = blurR; i < canvasb.height - blurR; i++) {
                for (let j = blurR; j < canvasb.width - blurR; j++) {
                    let totalr = 0
                    let totalg = 0
                    let totalb = 0
                    for (let dx = -blurR; dx <= blurR; dx++) {
                        for (let dy = -blurR; dy <= blurR; dy++) {
                            const x = i + dx
                            const y = j + dy

                            const p = x * canvasb.width + y
                            totalr += tmpPixelData[p*4 + 0]
                            totalg += tmpPixelData[p*4 + 1]
                            totalb += tmpPixelData[p*4 + 2]
                        }
                    }
                    const p = i * canvasb.width + j
                    const totalNum = (2*blurR + 1)* (2*blurR + 1)
                    pixelData[p * 4 + 0] = totalr / totalNum
                    pixelData[p * 4 + 1] = totalg / totalNum
                    pixelData[p * 4 + 2] = totalb / totalNum
                }
            }

            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }

        function mosaicEffect() {
            const tmpImageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const tmpPixelData = tmpImageData.data

            const imageData = contexta.getImageData(0, 0, canvasa.width, canvasa.height)
            const pixelData = imageData.data

            const size = 16
            const totalNum = size*size

            for (let i = 0; i < canvasb.height; i+=size) {
                for (let j = 0; j < canvasb.width; j+=size) {
                    let totalr = 0
                    let totalg = 0
                    let totalb = 0
                    for (let dx = 0; dx < size; dx++) {
                        for (let dy = 0; dy < size; dy++) {
                            const x = i + dx
                            const y = j + dy

                            const p = x * canvasb.width + y
                            totalr += tmpPixelData[p * 4 + 0]
                            totalg += tmpPixelData[p * 4 + 1]
                            totalb += tmpPixelData[p * 4 + 2]
                        }
                    }
                    
                    const resr = totalr / totalNum
                    const resg = totalg / totalNum
                    const resb = totalb / totalNum
                    
                    for (let dx = 0; dx < size; dx++) {
                        for (let dy = 0; dy < size; dy++) {
                            const x = i + dx
                            const y = j + dy

                            const p = x * canvasb.width + y
                            pixelData[p * 4 + 0] = resr
                            pixelData[p * 4 + 1] = resg
                            pixelData[p * 4 + 2] = resb
                        }
                    }
                }
            }


            contextb.putImageData(imageData, 0, 0, 0, 0, canvasb.width, canvasb.height)
        }
    </script>
</body>
</html>

图示:

有没有一段代码,让你为人类的智慧击节叫好? - 知乎

1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值