How to use the Renderscript blurring effect without artifacts?

android developer

Background

There are plenty of places (including here) to show how to use Renderscript to blur images, as such:

@TargetApi(VERSION_CODES.JELLY_BEAN_MR1)
public static Bitmap renderScriptBlur(Context context, Bitmap srcBitmap, @FloatRange(from = 0.0f, to = 25.0f) float radius) {
    if (srcBitmap == null)
        return null;
    Bitmap outputBitmap = null;
    RenderScript rs = null;
    try {
        rs = RenderScript.create(context);
        outputBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(outputBitmap);
        canvas.drawBitmap(srcBitmap, 0, 0, null);
        Allocation overlayAlloc = Allocation.createFromBitmap(rs, outputBitmap);
        ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        blur.setInput(overlayAlloc);
        blur.setRadius(radius);
        blur.forEach(overlayAlloc);
        overlayAlloc.copyTo(outputBitmap);
        return outputBitmap;
    } catch (Exception ex) {
        if (outputBitmap != null)
            outputBitmap.recycle();
        return srcBitmap;
    } finally {
        if (rs != null)
            rs.destroy();
    }
}

The problem

Usually it works great, but when using some images and/or radius-settings, the output image has artifacts that look like scan-lines:

enter image description here

What I've tried

I've found that there is a nicer blurring solutions (like here), but they don't use Renderscript and are also slow and memory-consuming.

I've also tried to make the input image smaller, but the output still has scanlines artifacts.

Finally, I've also reported about this, here.

The question

Is it possible to use Renderscript to blur images without those Artifcats? Is there anything wrong with what I wrote?

android developer

The problem was with the algorithm I used. Thanks to this github project, I've found the issue (which is probably not using the correct type fot the allocation) and used a nicer approach:

private static final AtomicReference<RenderScript> sRenderscript = new AtomicReference<>();


public static Bitmap blur(Context context, Bitmap bitmap) {
    return blur(context, bitmap, 4, false, false);
}

public static Bitmap blur(Context context, Bitmap bitmap, float radius) {
    return blur(context, bitmap, radius, false, false);
}

public static Bitmap blur(Context context, Bitmap bitmapOriginal, @FloatRange(from = 0.0f, to = 25.0f) float radius, boolean overrideOriginal, boolean recycleOriginal) {
    if (bitmapOriginal == null || bitmapOriginal.isRecycled())
        return null;
    RenderScript rs = sRenderscript.get();
    if (rs == null)
        if (!sRenderscript.compareAndSet(null, rs = RenderScript.create(context)) && rs != null)
            rs.destroy();
        else
            rs = sRenderscript.get();
    final Bitmap inputBitmap = bitmapOriginal.getConfig() == Config.ARGB_8888 ? bitmapOriginal : bitmapOriginal.copy(Config.ARGB_8888, true);
    final Bitmap outputBitmap = overrideOriginal ? bitmapOriginal : Bitmap.createBitmap(bitmapOriginal.getWidth(), bitmapOriginal.getHeight(), Config.ARGB_8888);
    final Allocation input = Allocation.createFromBitmap(rs, inputBitmap);
    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);
    if (recycleOriginal && !overrideOriginal)
        bitmapOriginal.recycle();
    output.copyTo(outputBitmap);
    return outputBitmap;
}

Now it all works nicely.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to blur an image without blurring the text?

Change blurring effect of UINavigationBar

How to use \ in a string without it's escape effect

How to use different kernel shapes while blurring an image?

How to use sap.m.Shell together with sap.ui.unified.Shell without artifacts

Canvas: Resizing image without blurring

How to versionate artifacts on Artifactory without overwriting

How to use artifactoryPublish to publish release and debug artifacts

How to stretch a WebGL canvas without blurring? The style "image-rendering" doesn't work

Name of Effect and How to Use

Android Canvas.DrawBitmap without blurring/AntiAliasing?

How to clear screen artifacts without rebooting Windows (multiple versions)

how to use ripple effect for a button

How to use axios in Effect Hook?

How to use registry scopes with Yarn 2.0 and Azure Artifacts

How do I force Maven to use external repos to retrieve artifacts?

How to programmatically use older snapshot artifacts stored in Nexus

How to use japicmp to compare between artifacts generated in current and previous build

How to apply the BackdropFilter blurring ONLY on the Drawer?

How to make blur effect without white light?

How to delete a record without immediate database effect

How to call virtual method without polymorphic effect?

Javascript: How to create a dropdown effect? (Without JQuery)

Uncheck use Androidx artifacts

Can you use a templatefile as an output value in terraform without the EOF and EOT artifacts?

How to debug in .rs file with RenderScript?

Why does 2d canvas not scale without blurring?

Use 2 string replace without the first having effect on the second

How to use the MonadError with the effect type IO?