Where not specified this question is just building on top of the CameraCaptureActivity
within the grafika project found on github.
It has a built in blur effect that utilises a 3x3 kernel
kernel = new float[] {
1f/16f, 2f/16f, 1f/16f,
2f/16f, 4f/16f, 2f/16f,
1f/16f, 2f/16f, 1f/16f };
However this blur effect is not strong enough, im looking for something like what the gaussian effect can do on iOS with UIVisualEffectView
, it looks something like this:
A nice smooth heavy blur effect but so far the best ive managed is this:
As you can see it is not nearly as smooth and also a bit squarish.
I achieved this by converting to a 5x5 kernel generated using this handy tool with a sigma of 30 and kernel size of 5. It produces the following:
kernel = new float[] {
0.039911f, 0.039978f, 0.04f, 0.039978f, 0.039911f,
0.039978f, 0.040044f, 0.040067f, 0.040044f, 0.039978f,
0.04f, 0.040067f, 0.040089f, 0.040067f, 0.04f,
0.039978f, 0.040044f, 0.040067f, 0.040044f, 0.039978f,
0.039911f, 0.039978f, 0.04f, 0.039978f, 0.039911f
};
In order to get the to work within the Grafika
project i had to modify KERNEL_SIZE
and mTexOffset
within the Texture2dProgram
class
KERNEL_SIZE
is now 25
and mTextOffset
is now calculated like so:
public void setTexSize(int width, int height) {
float rw = 50.0f / width;
float rh = 50.0f / height;
float rw50 = rw * 0.5f;
float rh50 = rh * 0.5f;
mTexOffset = new float[] {
-rw, -rh, -rw50, -rh, 0f, -rh, rw50, -rh, rw, -rh,
-rw, -rh50, -rw50, -rh50, 0f, -rh50, rw50, -rh50, rw, -rh50,
-rw, 0f, -rw50, 0f, 0f, 0f, rw50, -0f, rw, 0f,
-rw, rh50, -rw50, rh50, 0f, rh50, rw50, rh50, rw, rh50,
-rw, rh, -rw50, rh, 0f, rh, rw50, rh, rw, rh
};
};
Does anyone have an suggestions on what i could modify to achieve an iOS like blur (i think iOS is also lightening pixels as well)? I think where i am really going wrong is the setTextSize() calculation, specifically the 50.0f
value, i have just plucked this from thin air and observed the effect it has
Convolution with an actual blur kernel is a computationally intensive task, even on a GPU. There are a few techniques that make it work better:
The Gaussian kernel can be decomposed into X and Y components, which are computed separately. This technique is used by image manipulation programs because it is relatively fast and accurate.
Instead of using the Gaussian kernel, you can use Poisson disc sampling to blur the image.
You can use a multi-pass Kawase filter as an approximation to a Gaussian filter.
Sampling from lower resolution mip maps will result in better performance for a given subjective blur quality.
You can sample from between texels in order to hijack texture interpolation and get more taps than you would otherwise get.
It will generally take some fine-tuning to get it to "look right" once you start making these tradeoffs. A good summary is available at An investigation of fast real-time GPU-based image blur algorithms (Filip S., 2014).