我对处理非常陌生。
我正在尝试创建一个在普通图像上应用马赛克效果的程序。我要达到的目的是为图像创建过滤器大小的块(例如30像素),并用该块的r,g,b颜色的平均值替换
这是我到目前为止所做的:
class ME {
PImage image;
ME(String imagename) {
this.image = loadImage(imagename);
}
void display(int length, int height ) {
image.resize(length, height);
image(this.image, 0, 0);
}
void effect(int filterationSize) {
print("smth");
image.loadPixels();
float r, g, b;
for (int v = 0; v < (width*height ); v += filterationSize*width)
{
for (int h = 0; h < width; h+=filterationSize)
{
r = g = b = 0;
for (int bH = 0; bH<filterationSize; bH++)
{
for (int bV = 0; bV<filterationSize; bV++)
{
int p = v+h+bH+bV*width;
if ( p < width*width)
{
r += (red(this.image.pixels[p]) / (filterationSize*filterationSize));
g += (green(this.image.pixels[p]) / (filterationSize*filterationSize));
b += (blue(this.image.pixels[p]) / (filterationSize*filterationSize));
}
}
}
for (int blockH = 0; blockH<filterationSize; blockH++)
{
for (int blockV = 0; blockV<filterationSize; blockV++)
{
int p = v+h+blockH+blockV*width;
if ( p < width*width)
{
this.image.pixels[p] = color(r, g, b);
}
}
}
}
}
this.image.updatePixels();
}
}
这是我的主要班级:
ME img ;
void setup(){
size(500 ,500);
img = new ME("image.png");
img.display(width , height);
}
void draw(){
img.effect(30);
}
但是最终,该图像与开始时的图像相同。
答案 0 :(得分:1)
将效果应用于图像后,您错过了显示图像:
void draw(){
img.effect(30);
img.display(width , height);
}
但是,您可能希望在图像加载后应用一次效果:
ME img;
void setup(){
size(500 ,500);
img = new ME("image.png");
img.display(width , height);
img.effect(30);
}
void draw(){
img.effect(30);
img.display(width, height);
}
进一步,您可以改进effect
算法。
计算图块数量,但请注意,行或列中的最后一个图块可能会被裁剪:
int tiles_x = width / filterationSize;
if ( width % filterationSize > 0 )
tiles_x += 1;
int tiles_y = height / filterationSize;
if ( height % filterationSize > 0 )
tiles_y += 1;
计算循环内图块的开始结束坐标和“大小”:
int start_x = tile_x*filterationSize;
int start_y = tile_y*filterationSize;
int end_x = min(start_x+filterationSize, width);
int end_y = min(start_y+filterationSize, height);
int size = (end_x-start_x) * (end_y-start_y);
现在很容易计算一个图块的像素平均值。完整的算法可能如下所示:
void effect(int filterationSize) {
image.loadPixels();
int tiles_x = width / filterationSize;
if ( width % filterationSize > 0 )
tiles_x += 1;
int tiles_y = height / filterationSize;
if ( height % filterationSize > 0 )
tiles_y += 1;
print( tiles_x, tiles_y );
for ( int tile_y = 0; tile_y < tiles_x; tile_y ++ ) {
for ( int tile_x = 0; tile_x < tiles_y; tile_x ++ ) {
int start_x = tile_x*filterationSize;
int start_y = tile_y*filterationSize;
int end_x = min(start_x+filterationSize, width);
int end_y = min(start_y+filterationSize, height);
int size = (end_x-start_x) * (end_y-start_y);
float r = 0, g = 0, b = 0;
for (int by = start_y; by < end_y; by++ ) {
for (int bx = start_x; bx < end_x; bx++ ) {
int p = by * width + bx;
r += red(this.image.pixels[p]) / size;
g += green(this.image.pixels[p]) / size;
b += blue(this.image.pixels[p]) / size;
}
}
for (int by = start_y; by < end_y; by++ ) {
for (int bx = start_x; bx < end_x; bx++ ) {
int p = by * width + bx;
this.image.pixels[p] = color(r, g, b);
}
}
}
}
this.image.updatePixels();
}
查看应用于256 * 256图像和图块长度为32的效果: