11

I am trying to blur an image with ScriptIntrinsicBlur from the RenderScript support library. I am using gradle and I have used this approach to use the Support Library version of RenderScript.

On my Nexus 4, everything works fine and is really fast, but when I try it on my Samsung Galaxy S with Android 2.3.3, the picture that I get looks like this:

noisy image

I am using Roman Nurik's tip for having the bitmap width as a multiple of 4, but I don't think that this is the cause of my problem. My blurring code looks exactly like in this post. Thanks for any advice.

Here's my code:

Getting Bitmap of the View and rescaling the Bitmap:

public static Bitmap loadBitmapFromView(View v) {
        v.setDrawingCacheEnabled(false);
        v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_LOW);
        v.setDrawingCacheEnabled(true);
        Bitmap b = v.getDrawingCache();
        return b;
    }

public static Bitmap scaledBitmap(Bitmap dest, float scale) {
        int scaledWidth = (int) (scale * dest.getWidth());
        if (scaledWidth % 4 != 0) { //workaround for bug explained here https://plus.google.com/+RomanNurik/posts/TLkVQC3M6jW
            scaledWidth = (scaledWidth / 4) * 4;
        }
        return Bitmap.createScaledBitmap(dest, scaledWidth, (int) (scale * dest.getHeight()), true);
    }

Renderscript code:

Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);

final RenderScript rs = RenderScript.create(context);
final Allocation input = Allocation.createFromBitmap(rs, sentBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
final Allocation output = Allocation.createTyped(rs, input.getType());
final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setRadius(radius);
script.setInput(input);
script.forEach(output);
output.copyTo(bitmap);
return bitmap;

I have noticed this error in the logcat output:

E/RenderScript_jni﹕ No GC methods

After that my application is frozen.

Community
  • 1
  • 1
Billda
  • 5,707
  • 2
  • 25
  • 44
  • It's mentioned in the [post](http://stackoverflow.com/a/19693912/1262089) that Gradle support is just for native RS and not RS support library. RS is for API 11+, maybe that's why it's not working on 2.3.3 with gradle. It works in eclipse. – Rahul Sainani Feb 04 '14 at 22:15
  • well, "However, it's possible to use some parts of the RS support library from Gradle already. If you want to use the RS intrinsics, you can link the Java part of the support library" looks like it is possible ;) – Billda Feb 04 '14 at 22:52
  • can you post the code you're using to create the bitmaps and the actual forEach invocation? – Tim Murray Feb 04 '14 at 22:57
  • I have edited my question with source codes – Billda Feb 05 '14 at 08:08
  • is the asset you're loading stored in drawable-nodpi? – Tim Murray Feb 05 '14 at 19:38
  • I am not loading stored asset, i am capturing view of my screen to bitmap and then blurring this bitmap. – Billda Feb 05 '14 at 19:50
  • 1
    Well, i kind of sorted out myself ... i have removed renderscrit-v8.jar from libs and from gradle dependencies and to "defaultConfig" part of android gradle settings i put "renderscriptSupportMode true" – Billda Feb 05 '14 at 20:46

1 Answers1

21

I was getting a very similar image from the ScriptInstinsicBlur in my application. It took a while to figure this out but it turns out that the MediaMetadataRetiever getFrameAt methods return a Bitmap config that is RGB_565. Applying the blur in renderscript gives you the funky results because it apparently doesn't work on 565 pixels.

Converting my Bitmap to a ARGB_8888 and then handing it to the renderscript gave me the blur I was looking for.

Hopefully this helps someone else.

This is the method I found to convert it. (It's from a SO post I don't have bookmarked)

 private Bitmap RGB565toARGB888(Bitmap img) {
    int numPixels = img.getWidth()* img.getHeight();
    int[] pixels = new int[numPixels];

    //Get JPEG pixels.  Each int is the color values for one pixel.
    img.getPixels(pixels, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight());

    //Create a Bitmap of the appropriate format.
    Bitmap result = Bitmap.createBitmap(img.getWidth(), img.getHeight(), Bitmap.Config.ARGB_8888);

    //Set RGB pixels.
    result.setPixels(pixels, 0, result.getWidth(), 0, 0, result.getWidth(), result.getHeight());
    return result;
}
Jeff
  • 2,198
  • 3
  • 21
  • 38