/*******************************************************************************
* Copyright 2017 Ivan Shubin http://galenframework.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.galenframework.rainbow4j.filters;
import com.galenframework.rainbow4j.BufferUtils;
import com.galenframework.rainbow4j.ImageHandler;
import java.awt.*;
import java.nio.ByteBuffer;
/**
* Created by ishubin on 2014/09/14.
*/
public class BlurFilter implements ImageFilter {
private int radius;
public BlurFilter(int radius) {
this.radius = radius;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
@Override
public void apply(ByteBuffer bytes, int width, int height, Rectangle area) {
if (area.width + area.x > width || area.height + area.y > height) {
throw new RuntimeException("Specified area is outside of image");
}
if (radius > 0) {
ByteBuffer copyBytes = BufferUtils.clone(bytes);
for (int yc = area.y; yc < area.y + area.height; yc++) {
for (int xc = area.x; xc < area.x + area.width; xc++) {
int startY = Math.max(yc - radius, area.y);
int startX = Math.max(xc - radius, area.x);
int endY = Math.min(yc + radius, area.height + area.y - 1);
int endX = Math.min(xc + radius, area.width + area.x - 1);
int ar = 0, ag = 0, ab = 0;
double sumWeight = 0;
double distance;
double dWeight;
for (int y = startY; y <= endY; y++) {
for (int x = startX; x <= endX; x++) {
int k = y * width * ImageHandler.BLOCK_SIZE + x * ImageHandler.BLOCK_SIZE;
int r = copyBytes.get(k) & 0xff;
int g = copyBytes.get(k + 1) & 0xff;
int b = copyBytes.get(k + 2) & 0xff;
distance = Math.max(Math.abs(x - xc), Math.abs(y - yc));
dWeight = 1 - distance/(radius + 1);
sumWeight += dWeight;
ar += r * dWeight;
ag += g * dWeight;
ab += b * dWeight;
}
}
int k = yc * width * ImageHandler.BLOCK_SIZE + xc * ImageHandler.BLOCK_SIZE;
bytes.put(k, (byte) (ar / sumWeight));
bytes.put(k + 1, (byte) (ag / sumWeight));
bytes.put(k + 2, (byte) (ab / sumWeight));
}
}
}
}
}