Sha*_*son 2 javascript canvas html5-canvas
我有一个遍历图像的脚本。图像开始像素化,然后在查看时变为非像素化。我通过调用此函数x多次实现了requestAnimationFrame
Images.prototype.setPixels = function() {
var sw = this.imageWidth,
sh = this.imageHeight,
imageData = this.context.getImageData( 0, 0, sw, sh ),
data = imageData.data,
y, x, n, m;
for ( y = 0; y < sh; y += this.pixelation ) {
for ( x = 0; x < sw; x += this.pixelation ) {
var red = data[((sw * y) + x) * 4];
var green = data[((sw * y) + x) * 4 + 1];
var blue = data[((sw * y) + x) * 4 + 2];
for ( n = 0; n < this.pixelation; n++ ) {
for ( m = 0; m < this.pixelation; m++ ) {
if ( x + m < sw ) {
data[((sw * (y + n)) + (x + m)) * 4] = red;
data[((sw * (y + n)) + (x + m)) * 4 + 1] = green;
data[((sw * (y + n)) + (x + m)) * 4 + 2] = blue;
}
}
}
}
}
this.context.putImageData( imageData, 0, 0 );
}
Run Code Online (Sandbox Code Playgroud)
问题:如何使单个像素比现在更大的块。现在它们很小,效果有点刺耳。我希望通过减少屏幕上的像素块,使其更大来解决此问题。
我希望这是有道理的,因为我的画布相当绿,所以您能做的任何正确的工作都将为我锦上添花!
实现这种效果的最好方法是,drawImage由于可以通过将imageSmoothingEnabled属性更改为false 来设置最近邻抗锯齿算法,因此只需使用并让浏览器处理像素化。
然后,将像素化为任何pixel_size的图像变为两步过程:
以其原始大小/ pixel_size绘制完整质量的图像(或canvas / video ...)。
在此阶段,每个“像素”为一个像素大。
再次绘制此小图像,但按pixel_size放大。为此,您只需要在其上方绘制画布即可。
现在每个像素都大了pixel_size。
与其处理难以阅读的drawImage的许多参数,不如通过使用ctx.scale()方法可以非常轻松地处理缩放。
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
function drawPixelated( source, pixel_size ) {
// scale down
ctx.scale(1 / pixel_size, 1 / pixel_size)
ctx.drawImage(source, 0, 0);
// make next drawing erase what's currently on the canvas
ctx.globalCompositeOperation = 'copy';
// nearest-neighbor
ctx.imageSmoothingEnabled = false;
// scale up
ctx.setTransform(pixel_size, 0, 0, pixel_size, 0, 0);
ctx.drawImage(canvas, 0, 0);
// reset all to defaults
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.globalCompositeOperation = 'source-over';
ctx.imageSmoothingEnabled = true;
}
const img = new Image();
img.onload = animeLoop;
img.src = "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
let size = 1;
let speed = 0.1;
function animeLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
size += speed;
if(size > 30 || size <= 1) {
speed *= -1
}
drawPixelated( img, size );
requestAnimationFrame(animeLoop);
}Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas" width="800" height="600"></canvas>Run Code Online (Sandbox Code Playgroud)
现在,对于那些真正需要使用ImageData的应用程序(例如因为它们正在生成像素艺术),那么知道您可以简单地使用相同的技术:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
function putPixelated( imageData, pixel_size ) {
ctx.putImageData(imageData, 0, 0);
// make next drawing erase what's currently on the canvas
ctx.globalCompositeOperation = 'copy';
// nearest-neighbor
ctx.imageSmoothingEnabled = false;
// scale up
ctx.setTransform(pixel_size, 0, 0, pixel_size, 0, 0);
ctx.drawImage(canvas, 0, 0);
// reset all to defaults
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.globalCompositeOperation = 'source-over';
ctx.imageSmoothingEnabled = true;
}
const img = new ImageData(16, 16);
crypto.getRandomValues(img.data);
let size = 1;
let speed = 0.1;
animeLoop();
function animeLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
size += speed;
if(size > 30 || size <= 1) {
speed *= -1
}
putPixelated( img, size );
requestAnimationFrame(animeLoop);
}Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas" width="800" height="600"></canvas>Run Code Online (Sandbox Code Playgroud)