13

RenderScript ScriptIntrinsic Blur にいくつか問題があります。一部のデバイスでは、画像全体がぼやけません。入力画像を縮小し、幅が 4 の倍数であることを確認します (Roman Nurik によって提案されているため: https://plus.google.com/+RomanNurik/posts/TLkVQC3M6jW )

@SuppressLint("NewApi")
private Bitmap blurRenderScript(Bitmap smallBitmap) {

    Bitmap output = Bitmap.createBitmap(smallBitmap.getWidth(), smallBitmap.getHeight(), smallBitmap.getConfig());

    RenderScript rs = RenderScript.create(getContext());
    ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
    Allocation inAlloc = Allocation.createFromBitmap(rs, smallBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
    Allocation outAlloc = Allocation.createFromBitmap(rs, output);
    script.setRadius(BLUR_RADIUS);
    script.setInput(inAlloc);
    script.forEach(outAlloc);
    outAlloc.copyTo(output);

    rs.destroy();

    MutableBitmap.delete(smallBitmap);

    return output;
}

Nexus 4で動作しています:

ボケる前のNexus 4ぼかした後の Nexus 4

ただし、Galaxy S4 では、右側に透明なエッジがあります。

ボケる前のGalaxy S4ぼかし後のGalaxy S4

私が言いたいことを理解していただければ幸いです。画像を gimp で開くと、よりよく見えます。画像サイズには依存しません。大きい画像と小さい画像でも試してみましたが、結果は常に同じでした。たとえば、Nexus 7 2012 でも発生します。また、透明なアーティファクトが下または左端にある場合があります。よろしくお願いします。

Nexus 4: 4.4.2/ビルド番号 KOT49H Galaxy S4: 4.2.2/ビルド番号 JDQ39.I9505XXUDMGG

4

4 に答える 4

3

なぜこれがうまくいくのかわかりませんが、私にとってはうまくいきました..

代わりに試してください

    Bitmap output = Bitmap.createBitmap(smallBitmap.getWidth(), smallBitmap.getHeight(), smallBitmap.getConfig());

Bitmap.Config.ARGB_8888 を次のように渡します

    Bitmap output = Bitmap.createBitmap(smallBitmap.getWidth(), smallBitmap.getHeight(), Bitmap.Config.ARGB_8888);
于 2014-03-21T16:29:29.637 に答える
2

I am assuming you are using android.renderscript instead of the support lib android.v8.renderscript. (or a old support lib?)

If that is true, then it is a known bug that can only be fixed by a system upgrade, which may not be feasible to the users.

One way to workaround this is to use RenderScript Support lib: you can find the detailed instructions here:http://developer.android.com/guide/topics/renderscript/compute.html#access-rs-apis

Basically you just need to change the import:

import android.support.v8.renderscript.*;

And config your build.gradle:

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19

        renderscriptTargetApi 18
        renderscriptSupportModeEnabled true

    }
}

There are several advantages of using support lib:

  1. Support devices back to API 8.
  2. Can be updated with Build-Tools to incorporate bugs fixes and workaround.

On the downside, to achieve this, it needs to bundle several shared libraries which will make your app beefier.

于 2016-05-13T18:23:13.100 に答える
1

この透明度を取り除く作業はまだうまくいかなかったので、ぼかした後、画像を 25 ピクセルだけトリミングするだけで終わりました。確かに理想的ではありませんが、私の ScriptIntrinsicBlur のアプリケーションには十分に機能しました。

output = Bitmap.createBitmap(nbm, 25, 25, bm.getWidth() - 25, bm.getHeight() - 25);
于 2015-03-07T02:41:50.843 に答える
-3

ひ!これは、より強いガウスぼかしを得るために ScriptIntrinsicBlur の半径を大きくする必要があるすべての人のためのものです。

半径を 25 より大きくする代わりに、画像を縮小しても同じ結果が得られます。GaussianBlur というクラスを書きました。以下に、使用方法とクラス全体の実装を示します。

使用法:

    GaussianBlur gaussian = new GaussianBlur(context);
    gaussian.setMaxImageSize(60);
    gaussian.setRadius(25); //max

    Bitmap output = gaussian.render(<your bitmap>,true);
    Drawable d = new BitmapDrawable(getResources(),output);

クラス:

public class GaussianBlur {
private final int DEFAULT_RADIUS = 25;
private final float DEFAULT_MAX_IMAGE_SIZE = 400;

private Context context;
private int radius;
private float maxImageSize;

public GaussianBlur(Context context) {
    this.context = context;
    setRadius(DEFAULT_RADIUS);
    setMaxImageSize(DEFAULT_MAX_IMAGE_SIZE);
}

public Bitmap render(Bitmap bitmap, boolean scaleDown) {
    RenderScript rs = RenderScript.create(context);

    if (scaleDown) {
        bitmap = scaleDown(bitmap);
    }

    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);

    Allocation inAlloc = Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
    Allocation outAlloc = Allocation.createFromBitmap(rs, output);

    ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, inAlloc.getElement()); // Element.U8_4(rs));
    script.setRadius(getRadius());
    script.setInput(inAlloc);
    script.forEach(outAlloc);
    outAlloc.copyTo(output);

    rs.destroy();

    return output;
}

public Bitmap scaleDown(Bitmap input) {
    float ratio = Math.min((float) getMaxImageSize() / input.getWidth(), (float) getMaxImageSize() / input.getHeight());
    int width = Math.round((float) ratio * input.getWidth());
    int height = Math.round((float) ratio * input.getHeight());

    return Bitmap.createScaledBitmap(input, width, height, true);
}

public int getRadius() {
    return radius;
}

public void setRadius(int radius) {
    this.radius = radius;
}

public float getMaxImageSize() {
    return maxImageSize;
}

public void setMaxImageSize(float maxImageSize) {
    this.maxImageSize = maxImageSize;
}

}

;)

于 2014-10-17T13:52:50.893 に答える