简体   繁体   中英

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. 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.

The gray.rs file looks like the following:

// 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. 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:

// 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被清零以制作完全透明的图像。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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