0

我编写了以下代码来使图像变灰。在早期的项目中,我对 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 分配、应用内核函数并将结果放到屏幕上来准备整个渲染脚本。

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 变为空白。为什么 ?我找不到我的错误。我按照官方文档中的步骤进行操作,但也许我错过了一些东西

4

2 回答 2

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);
}
于 2019-07-16T02:02:38.280 回答
0

另一种选择是在您的权重向量中使用 1.f,否则您的 alpha 将被归零,从而生成完全透明的图像。

于 2019-07-20T21:10:03.193 回答