• 喜欢前端以及PHP的朋友们可以加PHP同好会QQ群 点击加入qq群
  • 最近在写一个项目---"小A微信托管平台",大家可以去帮忙测试一下!功能在不断完善中,敬请关注!点击进入
  • 本站使用了PHP8.1与HTTP2.0协议,速度简直超级快有木有?

使用 Canvas 制作图片油画效果

前端 Mr.Adam 4年前 (2021-02-25) 1671次浏览 已收录 0个评论

使用 Canvas 制作图片油画效果

使用 Canvas 制作图片油画效果

借鉴了https://wow.techbrood.com/fiddle/31235的例子,里面的参数自己手动调了调,效果如下:
使用 Canvas 制作图片油画效果
所有代码:

<!DOCTYPE html>
<html>
<head>
	<title>油画效果滤镜</title>
	<style type="text/css">
		body {
		    text-align: center;
		    background: #ececec;
		    font-family: Tahoma, Geneva, sans-serif
		}
		section {
		    display: inline-block
		}
		canvas {
		    border: 1px solid #000
		}
	</style>
</head>
<body>
<section>
    <h2>原图</h2>
    <canvas id="canvas"></canvas>
</section>
<section>
    <h2>油画滤镜特效</h2>
  <canvas id="dest-canvas"></canvas>
</section>
</body>
<script type="text/javascript">
	var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    img = new Image(),
    effectEl = document.getElementById("effect"),
    settings = {
        radius: 1,
        intensity: 40,
        ApplyFilter: function() {
            doOilPaintEffect();
        }
    }

img.addEventListener('load', function() {
    // reduced the size by half for pen and performance.
    canvas.width = (this.width / 2);
    canvas.height = (this.height / 2);
    ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
    doOilPaintEffect();
});

img.crossOrigin = "Anonymous";
img.src = "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2837799228,776641844&fm=26&gp=0.jpg";

var gui = new dat.GUI();
gui.add(settings, 'intensity');
gui.add(settings, 'radius');
gui.add(settings, 'ApplyFilter');

function doOilPaintEffect() {
    oilPaintEffect(canvas, settings.radius, settings.intensity);
}

function oilPaintEffect(canvas, radius, intensity) {
    var width = canvas.width,
        height = canvas.height,
        imgData = ctx.getImageData(0, 0, width, height),
        pixData = imgData.data,
        // change to createElement getting added element just for the demo
        destCanvas = document.getElementById("dest-canvas"),
        dCtx = destCanvas.getContext("2d"),
        pixelIntensityCount = [];

    destCanvas.width = width;
    destCanvas.height = height;

    var destImageData = dCtx.createImageData(width, height),
        destPixData = destImageData.data,
        intensityLUT = [],
        rgbLUT = [];

    for (var y = 0; y < height; y++) {
        intensityLUT[y] = [];
        rgbLUT[y] = [];
        for (var x = 0; x < width; x++) {
            var idx = (y * width + x) * 4,
                r = pixData[idx],
                g = pixData[idx + 1],
                b = pixData[idx + 2],
                avg = (r + g + b) / 3;

            intensityLUT[y][x] = Math.round((avg * intensity) / 255);
            rgbLUT[y][x] = {
                r: r,
                g: g,
                b: b
            };
        }
    }


    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            pixelIntensityCount = [];

            // Find intensities of nearest pixels within radius.
            for (var yy = -radius; yy <= radius; yy++) {
                for (var xx = -radius; xx <= radius; xx++) {
                    if (y + yy > 0 && y + yy < height && x + xx > 0 && x + xx < width) {
                        var intensityVal = intensityLUT[y + yy][x + xx];

                        if (!pixelIntensityCount[intensityVal]) {
                            pixelIntensityCount[intensityVal] = {
                                val: 1,
                                r: rgbLUT[y + yy][x + xx].r,
                                g: rgbLUT[y + yy][x + xx].g,
                                b: rgbLUT[y + yy][x + xx].b
                            }
                        } else {
                            pixelIntensityCount[intensityVal].val++;
                            pixelIntensityCount[intensityVal].r += rgbLUT[y + yy][x + xx].r;
                            pixelIntensityCount[intensityVal].g += rgbLUT[y + yy][x + xx].g;
                            pixelIntensityCount[intensityVal].b += rgbLUT[y + yy][x + xx].b;
                        }
                    }
                }
            }

            pixelIntensityCount.sort(function(a, b) {
                return b.val - a.val;
            });

            var curMax = pixelIntensityCount[0].val,
                dIdx = (y * width + x) * 4;

            destPixData[dIdx] = ~~(pixelIntensityCount[0].r / curMax);
            destPixData[dIdx + 1] = ~~(pixelIntensityCount[0].g / curMax);
            destPixData[dIdx + 2] = ~~(pixelIntensityCount[0].b / curMax);
            destPixData[dIdx + 3] = 255;
        }
    }
    dCtx.putImageData(destImageData, 0, 0);
}
</script>
</html>

小 A 空间 , 版权所有丨如未注明转载 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明使用 Canvas 制作图片油画效果
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址