Я пытаюсь наложить эффект мозаики на изображение при обработке, но изображение остается прежним?
Я очень новичок в обработке.
Я пытаюсь создать программу, которая применяет эффект мозаики к нормальному изображению. Я пытаюсь добиться, чтобы изображение создало блоки размером фильтра (например, 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);
}
Но в итоге изображение оказывается тем же самым, что и самое начало.
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: