以下代码使用GPU.js(WebGL的包装器),通过简单地编写JS函数,可以轻松地使用WebGL运行矩阵运算,我在画布上渲染图像,但我想调整其大小。我读过有关最近邻插值的信息,但是我对如何实现它感到困惑。我已经设置了调整大小内核,剩下要做的就是内插逻辑。
笔记:
在内核函数中this.thread.x
,当前索引在this.thread.y
,和中可用this.thread.z
,具体取决于内核正在计算的矩阵的维数。
您会注意到画布的尺寸很奇怪。这是与WebGL纹理处理相关的GPU.js的“功能”(我认为他们计划稍后进行修复)。
编辑:取得了进步,但还不够完善:http : //jsfiddle.net/0dusaytk/59/
const canvas1 = document.createElement("canvas");
const context1 = canvas1.getContext("webgl2");
document.body.appendChild(canvas1);
const canvas2 = document.createElement("canvas");
const context2 = canvas2.getContext("2d");
const gpu = new GPU({
canvas: canvas1,
webGl: context1
});
const image = new Image();
image.crossOrigin = "Anonymous";
image.src = "https://i.imgur.com/sl2J6jm.jpg";
image.onload = function() {
const length = 4 * image.height * image.width;
const gpuTexturize = gpu
.createKernel(function(sprite) {
return sprite[this.thread.x];
})
.setOutput([length])
.setOutputToTexture(true);
const gpuResize = gpu
.createKernel(function(sprite, w, h) {
return sprite[this.thread.x];
})
.setOutput([length])
.setOutputToTexture(true);
const gpuRender = gpu
.createKernel(function(sprite, w, h) {
var index = this.thread.x * 4 + (h - this.thread.y) * w * 4;
var r = sprite[index];
var g = sprite[index + 1];
var b = sprite[index + 2];
this.color(r / 255, g / 255, b / 255);
})
.setOutput([image.width, image.height])
.setGraphical(true);
canvas2.width = image.width;
canvas2.height = image.height;
context2.drawImage(image, 0, 0);
const imgData = context2.getImageData(
0,
0,
canvas2.width,
canvas2.height
);
const texture = gpuTexturize(imgData.data);
const resized = gpuResize(texture, 100, 100);
gpuRender(resized, image.width, image.height);
};
body {
background-color: #3a4659;
}
canvas {
background-color: #bcc8db;
}
<script src="https://rawgit.com/gpujs/gpu.js/develop/bin/gpu.js"></script>
我将第二个画布添加了像素化渲染,以便将该实现与浏览器的CSS默认方法进行比较。
演示:https : //codepen.io/rafaelcastrocouto/pen/pOaaEd
const scale = 4;
// canvas1 will be handled by the gpu
const canvas1 = document.createElement("canvas");
canvas1.className = 'c1';
const context1 = canvas1.getContext("webgl2");
const gpu = new GPU({
canvas: canvas1,
webGl: context1
});
document.body.appendChild(canvas1);
// canvas2 will render the image
const canvas2 = document.createElement("canvas");
canvas2.className = 'c2';
const context2 = canvas2.getContext("2d");
document.body.appendChild(canvas2);
canvas2.style.transform = 'scale('+scale+')';
// load the image
const image = new Image();
image.crossOrigin = "Anonymous";
image.src = "https://placeholdit.imgix.net/~text?txtsize=20&txtpad=1&bg=000&txtclr=fff&txt=64x32&w=64&h=32";
image.onload = function() {
// render image to canvas2
canvas2.width = image.width;
canvas2.height = image.height;
context2.drawImage(image, 0, 0);
// scale imageData
const imgData = context2.getImageData(0,0,image.width,image.height);
const gpuRender = gpu
.createKernel(function(sprite) {
var x = floor(this.thread.x/this.constants.s) * 4;
var y = floor(this.constants.h - this.thread.y/this.constants.s) * 4 * this.constants.w;
var index = x + y;
var r = sprite[ index ]/255;
var g = sprite[index+1]/255;
var b = sprite[index+2]/255;
var a = sprite[index+3]/255;
this.color(r, g, b, a);
},{
constants: {
w: image.width,
h: image.height,
s: scale
}
})
.setOutput([image.width*scale, image.height*scale])
.setGraphical(true);
gpuRender(imgData.data);
};
body {
background-color: #3a4659;
}
canvas {
background-color: #bcc8db;
display: block;
margin: 4em;
}
.c2 {
image-rendering: pixelated;
transform-origin: 0;
}
<script src="https://rawgit.com/gpujs/gpu.js/develop/bin/gpu.js"></script>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句