简体   繁体   English

Android - 使用Renderscript渲染图像不起作用

[英]Android - Graying out image using Renderscript does not work

I have written the following code to gray out an image. 我编写了以下代码来灰化图像。 In earlier projects, I made some experiences with JNI and now, I also wanted to try out Renderscript. 在早期的项目中,我为JNI做了一些经验,现在,我也想尝试使用Renderscript。 So, I write the following code: 所以,我写下面的代码:

// 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);
    }
}

As you can see, I load the image, prepare the whole renderscript stuff by creating the IN/OUT allocations, applying the kernel function and putting the result onto the screen. 如您所见,我加载图像,通过创建IN / OUT分配,应用内核函数并将结果放到屏幕上来准备整个renderscript内容。

The gray.rs file looks like the following: 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);
}

When I run the project, the following happens: 当我运行该项目时,会发生以下情况:

Outcome : 结果:

在此输入图像描述

So, the ImageView gets blank after I click the button and graying out process starts. 因此,单击按钮后,ImageView变为空白,并且灰色处理过程开始。 Why ? 为什么? I could not find my mistake. 我找不到我的错误。 I followed the steps in the official documentation but maybe I miss something 我按照官方文档中的步骤操作,但也许我想念一些东西

Change rs file as below works for me: 更改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.f,否则你的alpha被清零以制作完全透明的图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM