如何使用没有任何瑕疵的Renderscript模糊效果? [英] How to use the Renderscript blurring effect without artifacts?
问题描述
有很多地方(包括 这里 ),以展示如何使用Renderscript来模糊的图像,因为这样的:
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:
我发现有一个更好的解决方案,模糊(如 这里 )但它们不使用Renderscript并且也缓慢和存储器消耗。
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.
最后,我也报这个, < STRONG>这里 。
Finally, I've also reported about this, here.
时有可能使用Renderscript模糊图像,而这些Artifcats?这有什么错我写的?
Is it possible to use Renderscript to blur images without those Artifcats? Is there anything wrong with what I wrote?
推荐答案
的问题是与我所使用的算法。由于 此github上 项目,我发现这个问题(这可能是没有使用正确的类型FOT分配),并使用了更好的方法:
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.
这篇关于如何使用没有任何瑕疵的Renderscript模糊效果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!