我正在尝试产生一个以源图像开头的函数,产生噪声,然后使用噪声使图像失真。我首先创建噪声,然后将其转换为矢量场,然后重新映射坐标,并以正确的坐标将像素拉出图像。最后,我将提取的像素重新组合为图像。
到目前为止,我的代码如下:
function distort(sourceImage){
let vectorField = [];
var amount = 100;
var scale = 0.01;
for (x = 0; x < sourceImage.width; x++){
let row = [];
for (y = 0; y < sourceImage.height; y++){
let vector = createVector(amount*(noise(scale*x,scale*y)-0.5), 4*amount*(noise(100+scale*x,scale*y)-0.5))
row.push(vector);
}
vectorField.push(row);
}
var result = [];
sourceImage.loadPixels();
for (i = 0; i < sourceImage.width; i++){ //sourceImage.width
for (j = 0; j < sourceImage.height; j += 4){ //sourceImage.height
var res = vectorField[i][j];
//console.log(res);
var ii = constrain(floor(i + res.x), 0, sourceImage.width - 1);
var jj = constrain(floor(j + res.y), 0, sourceImage.height - 1);
//console.log(ii, jj);
result[i * sourceImage.width + j] = color(sourceImage.pixels[ii * sourceImage.width + jj], sourceImage.pixels[ii * sourceImage.width + jj + 1], sourceImage.pixels[ii * sourceImage.width + jj + 2], sourceImage.pixels[ii * sourceImage.width + jj + 3]);
}
}
//console.log(result)
//console.log(sourceImage.pixels[0 + sourceImage.width * 0])
for (n=0; n<sourceImage.width; n++) {
for(m=0; m<sourceImage.height; m++){
index = (n * sourceImage.width + m) * 4;
if (index >= 4194300){
index = 4194300;
}
sourceImage.pixels[index] = red(result[index]);
sourceImage.pixels[index + 1] = green(result[index]);
sourceImage.pixels[index + 2] = blue(result[index]);
sourceImage.pixels[index + 3] = alpha(result[index]);
}
}
sourceImage.updatePixels();
image(sourceImage, 0, 0, size, size);
}
除了结果,我在画布的顶部第4层得到了4个噪点。噪点尤其包括许多我不知道在源图像中的像素(即蓝色像素;我要变形的图像是红色和白色)。可以将噪声识别为已开始作为源图像,但是会失真并且具有上述伪像。
作为比较:
您没有完全处理矢量场,必须从该场读取每个矢量。实际上,您只读取了向量的每个第4个元素
for (j = 0; j < sourceImage.height; j += 4)
for (j = 0; j < sourceImage.height; j++)
此外,源索引的计算是错误的。请注意,必须将行(jj
)的控制变量乘以高度。数组中像素的索引必须乘以4,因为每个像素包含4个颜色通道:
ii * sourceImage.width + jj
(jj * sourceImage.width + ii) * 4
目标索引的计算也是错误的:
index = (n * sourceImage.width + m) * 4;
index = (m * sourceImage.width + n) * 4;
注意,result
每个像素包含1个元素,byut sourceImage.pixels
每个像素包含4个元素。因此,从结果中读取的索引与访问目标的索引是不同的:
let result_i = m * sourceImage.width + n;
let target_i = result_i * 4;
例如:
let result = [];
for (let j = 0; j < sourceImage.height; j++) {
for (let i = 0; i < sourceImage.width; i++) {
let res = vectorField[i][j];
let ii = constrain(floor(i + res.x), 0, sourceImage.width - 1);
let jj = constrain(floor(j + res.y), 0, sourceImage.height - 1);
let source_i = (jj * sourceImage.width + ii) * 4;
let col = color(
sourceImage.pixels[source_i],
sourceImage.pixels[source_i + 1],
sourceImage.pixels[source_i + 2],
sourceImage.pixels[source_i + 3]);
result.push(col);
}
}
for(let m = 0; m < sourceImage.height; m++) {
for (let n = 0; n < sourceImage.width; n++) {
let result_i = m * sourceImage.width + n;
let target_i = result_i * 4;
let col = result[result_i];
sourceImage.pixels[target_i] = red(col);
sourceImage.pixels[target_i + 1] = green(col);
sourceImage.pixels[target_i + 2] = blue(col);
sourceImage.pixels[target_i + 3] = alpha(col);
}
}