Search code examples
androidrenderscript

Chain 2 Renderscript Intrinsics : Blur & ColorMatrix


I am trying to chain two Renderscripts : ScriptIntrinsicBlur and ScriptIntrinsicColorMatrix.
I want to blur and image and then apply a color filter to it.

Here is my current code (I tried many different implementations, including ScriptGroups, that I can't get to work :

final ScriptIntrinsicBlur scriptBlur = ScriptIntrinsicBlur.create(
        mRenderScript,
        Element.U8_4(mRenderScript));
final Allocation input = Allocation.createFromBitmap(mRenderScript,
        bmp);
Bitmap blurOutBitmap = bmp.copy(bmp.getConfig(), true);
final Allocation output = Allocation.createFromBitmap(
        mRenderScript, blurOutBitmap);

scriptBlur.setRadius(mBlur_Radius);
scriptBlur.setInput(input);
scriptBlur.forEach(output);
bmp.recycle();
output.copyTo(blurOutBitmap);

mRenderScript.finish();

final ScriptIntrinsicColorMatrix scriptColor = ScriptIntrinsicColorMatrix
        .create(mRenderScript, Element.U8_4(mRenderScript));

/** for a first test, I am using a simple blue filter **/
Matrix3f mat = new Matrix3f(new float[] {
        1, 0, 1,
        0, 1, 1,
        0, 0, 1
});
scriptColor.setColorMatrix(mat);

final Allocation colorInput = Allocation.createFromBitmap(mRenderScript,
        blurOutBitmap);
Bitmap outBitmap = bmp.copy(blurOutBitmap.getConfig(), true);
final Allocation colorOutput = Allocation.createFromBitmap(
        mRenderScript, outBitmap);

scriptColor.forEach(colorInput, colorOutput);
blurOutBitmap.recycle();
colorOutput.copyTo(outBitmap);
displayBitmap(outBitmap);

This code produces very ugly artifacts on the image (parallel red lines) and if I try to use a ScriptGroup instead it simply crashes.
Does anybody with Renderscript Experience can help me decipher why ? Since there are very few samples or documentation on that topic, I am stuck trying random modifications.


Solution

  • Here is the correct way to do this (or at least one that works, this case is a bit buggy) :

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lenna);
    
    ScriptIntrinsicBlur scriptBlur = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript));
    scriptBlur.setRadius(5f);
    
    ScriptIntrinsicColorMatrix scriptColor = ScriptIntrinsicColorMatrix.create(mRenderScript, Element.U8_4(mRenderScript));
    
    final Allocation input = Allocation.createFromBitmap(mRenderScript, bitmap,
            Allocation.MipmapControl.MIPMAP_NONE,
            Allocation.USAGE_SCRIPT | Allocation.USAGE_SHARED);
    scriptBlur.setInput(input);
    Bitmap outBitmap = bitmap.copy(bitmap.getConfig(), true);
    final Allocation output = Allocation.createTyped(mRenderScript, input.getType());
    
    
    scriptColor.setColorMatrix(new Matrix4f(
            new float[]{1, 0f, 0f,   0,
                        1, 1,  0f,   0,
                        1, 0f, 1,    0,
                        0, 0,  0,    1}
    ));
    
    
    ScriptGroup.Builder b = new ScriptGroup.Builder(mRenderScript);
    b.addKernel(scriptBlur.getKernelID());
    b.addKernel(scriptColor.getKernelID());
    b.addConnection(input.getType(), scriptBlur.getKernelID(), scriptColor.getKernelID());
    ScriptGroup group = b.create();
    
    // group.setInput(scriptBlur.getKernelID(),input);
    group.setOutput(scriptColor.getKernelID(), output);
    
    
    group.execute();
    output.copyTo(outBitmap);
    return outBitmap;