我编写了以下代码以使图像变灰。在较早的项目中,我在JNI上有了一些经验,现在,我也想尝试Renderscript。 因此,我编写了以下代码:
// MainActivity.java
public class MainActivity extends AppCompatActivity {
private Bitmap mBitmapIn;
private Bitmap mBitmapOut;
private ImageView mImageView;
private Allocation mInAllocation;
private Allocation mOutAllocation;
private Button mButton;
private ScriptC_gray mScript;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton =(Button) findViewById(R.id.button);
// Initialize UI
mBitmapIn = loadBitmap(R.drawable.data);
mBitmapOut = Bitmap.createBitmap
(
mBitmapIn.getWidth(),
mBitmapIn.getHeight(),
mBitmapIn.getConfig()
);
mImageView = (ImageView) findViewById(R.id.imageView);
mImageView.setImageBitmap(mBitmapIn);
// Create renderScript
RenderScript rs = RenderScript.create(this);
// Allocate buffers
mInAllocation = Allocation.createFromBitmap(rs, mBitmapIn);
mOutAllocation = Allocation.createFromBitmap(rs, mBitmapOut);
mScript = new ScriptC_gray(rs); // Load script
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Invoke renderScript kernel and update imageView
mScript.forEach_gray(mInAllocation, mOutAllocation);
// Copy to bitmap and invalidate image view
mOutAllocation.copyTo(mBitmapOut);
mImageView.setImageBitmap(mBitmapOut);
}
});
}
/**
* Helper to load Bitmap from resource
*/
private Bitmap loadBitmap(int resource) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return BitmapFactory.decodeResource(getResources(), resource, options);
}
}
如您所见,我加载图像,通过创建IN / OUT分配,应用内核函数并将结果显示在屏幕上来准备整个renderscript内容。
gray.rs文件如下所示:
// gray.rs
#pragma version(1)
#pragma rs java_package_name(com.celik.abdullah.grayscale)
#pragma rs_fp_relaxed
const float4 weight = {0.299f, 0.587f, 0.114f, 0.0f}; // for grayscale
/*
* RenderScript kernel that performs grayscale manipulation
*/
uchar4 __attribute__((kernel)) gray(uchar4 in)
{
float4 inF = rsUnpackColor8888(in);
float4 outF = (float4){ dot(inF, weight) };
return rsPackColorTo8888(outF);
}
运行项目时,会发生以下情况:
结果:
因此,在单击按钮并开始变灰过程之后,ImageView变为空白。为什么呢我找不到我的错误。我遵循了官方文档中的步骤,但也许我错过了一些事情
答案 0 :(得分:0)
如下更改rs文件对我有用:
// gray.rs
#pragma version(1)
#pragma rs java_package_name(com.colibri.sample)
#pragma rs_fp_imprecise//rs_fp_relaxed//rs_fp_full//rs_fp_relaxed
const float3 gMonoMult = {0.299f, 0.587f, 0.114f};
/*
* RenderScript kernel that performs grayscale manipulation
*/
uchar4 __attribute__((kernel)) gray(uchar4 in)
{
// Transform the input pixel with a value range of [0, 255] to
// a float4 vector with a range of [0.0f, 1.0f]
float4 inF = rsUnpackColor8888(in);
// Calculate the dot product of the rgb channels and the global constant we defined and
// assign the result to each element in a float3 vector
float3 outF = dot(inF.rgb, gMonoMult);
// Transform the resulting color back to a uchar4 vector.
// Since the input color is just a float3 instead of a float4 the alpha value will
// be set to 255 or fully opaque.
return rsPackColorTo8888(outF);
}
答案 1 :(得分:0)
另一种选择是在权重向量中使用1.f,否则将alpha归零以制作完全透明的图像。