我制作了自己的影像過濾器棕褐色和模糊。當滑鼠點擊原始(左)影像時,意味著在處理后的(右)影像上創建徑向模糊效果。但是,經過測驗后,我發現它只有在加載時將滑鼠懸停在圖片上時才有效。然后,如果我單擊滑鼠,則會處理原始圖片,并且看起來過濾器在右側已處理的影像上變得更強,就像它在頂部應用了另一個過濾器一樣。我點擊得越多,這種情況就會持續下去。有人知道我做錯了什么嗎?我不確定我的代碼問題出在哪里。
var imgIn;
function preload() {
imgIn = loadImage("https://media.makeameme.org/created/doesnt-know-why-gxsyb3.jpg");
}
function setup() {
createCanvas((imgIn.width * 2), imgIn.height);
}
function draw() {
background(125);
image(imgIn, 0, 0);
image(earlyBirdFilter(imgIn), imgIn.width, 0);
noLoop();
}
function mousePressed() {
loop();
}
function earlyBirdFilter(img) {
var resultImg = createImage(img.width, img.height);
resultImg = sepiaFilter(img);
resultImg = radialBlurFilter(resultImg);
resultImg.updatePixels();
return resultImg;
}
function sepiaFilter(input) {
input.loadPixels();
for (var x = 0; x < input.width; x ) {
for (var y = 0; y < input.height; y ) {
var index = (y * input.width x) * 4;
var oldRed = input.pixels[index 0];
var oldGreen = input.pixels[index 1];
var oldBlue = input.pixels[index 2];
var newRed = (oldRed * .393) (oldGreen * .769) (oldBlue * .189)
var newGreen = (oldRed * .349) (oldGreen * .686) (oldBlue * .168)
var newBlue = (oldRed * .272) (oldGreen * .534) (oldBlue * .131)
input.pixels[index 0] = newRed;
input.pixels[index 1] = newGreen;
input.pixels[index 2] = newBlue;
input.pixels[index 3] = 255;
}
}
input.updatePixels();
return input;
}
function radialBlurFilter(input) {
var matrixSize = matrix.length;
input.loadPixels();
for (var x = 0; x < input.width; x ) {
for (var y = 0; y < input.height; y ) {
var index = (x y * input.width) * 4;
var c = convolution(x, y, matrix, matrixSize, input);
var d = dist(mouseX, mouseY, x, y);
var m = map(d, 100, 300, 0, 1);
var dynBlur = constrain(m, 0, 1);
var r = input.pixels[index 0];
var g = input.pixels[index 1];
var b = input.pixels[index 2];
input.pixels[index 0] = c[0] * dynBlur r * (1 - dynBlur);
input.pixels[index 1] = c[1] * dynBlur g * (1 - dynBlur);
input.pixels[index 2] = c[2] * dynBlur b * (1 - dynBlur);
input.pixels[index 3] = 255;
}
}
input.updatePixels();
return input;
}
function convolution(x, y, matrix, matrixSize, input) {
var totalRed = 0.0;
var totalGreen = 0.0;
var totalBlue = 0.0;
var offset = floor(matrixSize / 2);
// convolution matrix loop
for (var i = 0; i < matrixSize; i ) {
for (var j = 0; j < matrixSize; j ) {
// Get pixel loc within convolution matrix
var xloc = x i - offset;
var yloc = y j - offset;
var index = (xloc input.width * yloc) * 4;
index = constrain(index, 0, input.pixels.length - 1);
// multiply all values with the mask and sum up
totalRed = input.pixels[index 0] * matrix[i][j];
totalGreen = input.pixels[index 1] * matrix[i][j];
totalBlue = input.pixels[index 2] * matrix[i][j];
}
}
// return the new color
return [totalRed, totalGreen, totalBlue];
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
uj5u.com熱心網友回復:
正如 Sam 在評論中提到的,您每次都將過濾器重新應用于相同的像素:因此會產生累積效應。
p5.Image您可以簡單地使用復制輸入get()并將過濾器應用于該輸入而不是原始影像(在第一個過濾器被更改之后):
var imgIn;
var matrix = [[1,1,1],
[1,3,1],
[1,1,1]];
function preload() {
imgIn = loadImage("https://media.makeameme.org/created/doesnt-know-why-gxsyb3.jpg");
}
function setup() {
createCanvas((imgIn.width * 2), imgIn.height);
}
function draw() {
background(125);
image(imgIn, 0, 0);
image(earlyBirdFilter(imgIn), imgIn.width, 0);
noLoop();
}
function mousePressed() {
loop();
}
function earlyBirdFilter(img) {
var resultImg = createImage(img.width, img.height);
resultImg = sepiaFilter(img.get());
resultImg = radialBlurFilter(resultImg);
resultImg.updatePixels();
return resultImg;
}
function sepiaFilter(input) {
input.loadPixels();
for (var x = 0; x < input.width; x ) {
for (var y = 0; y < input.height; y ) {
var index = (y * input.width x) * 4;
var oldRed = input.pixels[index 0];
var oldGreen = input.pixels[index 1];
var oldBlue = input.pixels[index 2];
var newRed = (oldRed * .393) (oldGreen * .769) (oldBlue * .189)
var newGreen = (oldRed * .349) (oldGreen * .686) (oldBlue * .168)
var newBlue = (oldRed * .272) (oldGreen * .534) (oldBlue * .131)
input.pixels[index 0] = newRed;
input.pixels[index 1] = newGreen;
input.pixels[index 2] = newBlue;
input.pixels[index 3] = 255;
}
}
input.updatePixels();
return input;
}
function radialBlurFilter(input) {
var matrixSize = matrix.length;
input.loadPixels();
for (var x = 0; x < input.width; x ) {
for (var y = 0; y < input.height; y ) {
var index = (x y * input.width) * 4;
var c = convolution(x, y, matrix, matrixSize, input);
var d = dist(mouseX, mouseY, x, y);
var m = map(d, 100, 300, 0, 1);
var dynBlur = constrain(m, 0, 1);
var r = input.pixels[index 0];
var g = input.pixels[index 1];
var b = input.pixels[index 2];
input.pixels[index 0] = c[0] * dynBlur r * (1 - dynBlur);
input.pixels[index 1] = c[1] * dynBlur g * (1 - dynBlur);
input.pixels[index 2] = c[2] * dynBlur b * (1 - dynBlur);
input.pixels[index 3] = 255;
}
}
input.updatePixels();
return input;
}
function convolution(x, y, matrix, matrixSize, input) {
var totalRed = 0.0;
var totalGreen = 0.0;
var totalBlue = 0.0;
var offset = floor(matrixSize / 2);
// convolution matrix loop
for (var i = 0; i < matrixSize; i ) {
for (var j = 0; j < matrixSize; j ) {
// Get pixel loc within convolution matrix
var xloc = x i - offset;
var yloc = y j - offset;
var index = (xloc input.width * yloc) * 4;
index = constrain(index, 0, input.pixels.length - 1);
// multiply all values with the mask and sum up
totalRed = input.pixels[index 0] * matrix[i][j];
totalGreen = input.pixels[index 1] * matrix[i][j];
totalBlue = input.pixels[index 2] * matrix[i][j];
}
}
// return the new color
return [totalRed, totalGreen, totalBlue];
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
混亂可能來自本節?
function earlyBirdFilter(img) {
// you are creating a new image here
var resultImg = createImage(img.width, img.height);
// however, here, you're overriding the blank image above with the filtered `img`
resultImg = sepiaFilter(img);
resultImg = radialBlurFilter(resultImg);
resultImg.updatePixels();
return resultImg;
}
你有多種選擇,但它們都會做大致相同的事情。
One option, as mentioned above, you could simply clone the input image with get() first:
function earlyBirdFilter(img) {
var resultImg = createImage(img.width, img.height);
resultImg = sepiaFilter(img.get());
resultImg = radialBlurFilter(resultImg);
// this call to `updatePixels()` is a bit redundant since sepiaFilter and radialBlurFilter both call `updatePixels()` on the reference image passed as an argument
resultImg.updatePixels();
return resultImg;
}
Another option is to have your filter functions take an image as an input but also return a separate image as an output, for example:
function sepiaFilter(input) {
// copy input
let output = input.get();
input.loadPixels();
output.loadPixels();
let numPixels = input.pixels.length;
for(let index = 0 ; index < numPixels; index = 4){
var oldRed = input.pixels[index 0];
var oldGreen = input.pixels[index 1];
var oldBlue = input.pixels[index 2];
var newRed = (oldRed * .393) (oldGreen * .769) (oldBlue * .189);
var newGreen = (oldRed * .349) (oldGreen * .686) (oldBlue * .168);
var newBlue = (oldRed * .272) (oldGreen * .534) (oldBlue * .131);
output.pixels[index 0] = newRed;
output.pixels[index 1] = newGreen;
output.pixels[index 2] = newBlue;
// copy alpha channel
output.pixels[index 3] = input.pixels[index 3];
}
output.updatePixels();
return output;
}
(Also notice you call loop over the pixels[] array with a single for loop)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/442584.html
下一篇:將蒙版應用于影像
