我对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:
但在Galaxy S4上,右侧有透明边缘:
我希望你能看出我的意思 - 如果你打开gimp中的图片,或者你可以更好地看到它。它并不取决于图片大小。我也尝试了越来越大的图像,结果总是一样的。例如,它也发生在Nexus 7 2012上。此外,透明工件有时位于bottem或左边缘。在此先感谢您的帮助!
Nexus 4:4.4.2 /内部编号KOT49H Galaxy S4:4.2.2 / Build Number JDQ39.I9505XXUDMGG
答案 0 :(得分: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);
答案 1 :(得分:2)
我假设您使用的是android.renderscript而不是支持lib android.v8.renderscript。 (或旧的支持库?)
如果这是真的,那么这是一个已知的错误,只能通过系统升级修复,这可能对用户不可行。
解决此问题的一种方法是使用RenderScript支持库:您可以在此处找到详细说明:http://developer.android.com/guide/topics/renderscript/compute.html#access-rs-apis
基本上你只需要改变导入:
import android.support.v8.renderscript.*;
并配置你的build.gradle:
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 8
targetSdkVersion 19
renderscriptTargetApi 18
renderscriptSupportModeEnabled true
}
}
使用支持库有几个好处:
在缺点方面,要实现这一目标,它需要捆绑几个共享库,这将使您的应用程序更加强大。
答案 2 :(得分:1)
我仍然无法通过任何工作来消除这种透明度,因此我在模糊后将图像修剪为25像素。绝对不理想,但它对我的ScriptIntrinsicBlur应用程序运行良好:
output = Bitmap.createBitmap(nbm, 25, 25, bm.getWidth() - 25, bm.getHeight() - 25);
答案 3 :(得分:-3)
ħ!这适用于所有需要增加ScriptIntrinsicBlur半径以获得更高硬度模糊的人。
您可以缩小图像并获得相同的结果,而不是将半径设置为大于25。我写了一个名为GaussianBlur的类。 Bellow你可以看到如何使用,以及整个类的实现。
用法:
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;
}
}
)