我是Android Renderscript的新手。 我需要在RenderScript中编写卷积乘法,因为最终的应用程序将在Android上运行。数据流将成为一个图像。 更具体地说,我无法使用forEach功能编写核心逻辑,尽管我可以用Java编写,但速度太慢! 请帮忙! 史蒂夫
答案 0 :(得分:8)
在rsForEach调用(或其他Renderscript函数)期间,您可以通过将原始图像分配绑定到Renderscript中的指针来访问原始图像的邻近像素(或您正在使用的任何类型的数据)。作为数组访问。以下是基于HelloCompute示例的示例:
#pragma version(1)
#pragma rs java_package_name(com.android.example.hellocompute)
rs_allocation gIn;
rs_allocation gOut;
rs_script gScript;
static int mImageWidth;
const uchar4 *gPixels;
const float4 kWhite = {
1.0f, 1.0f, 1.0f, 1.0f
};
const float4 kBlack = {
0.0f, 0.0f, 0.0f, 1.0f
};
void init() {
}
static const int kBlurWidth = 20;
static const float kMultiplier = 1.0f / (float)(kBlurWidth * 2 + 1);
void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) {
float4 original = rsUnpackColor8888(*v_in);
float4 colour = original * kMultiplier;
int y_component = mImageWidth * y;
for ( int i = -kBlurWidth; i < 0; i++) {
float4 temp_colour;
if ( (int)x + i >= 0) {
temp_colour = rsUnpackColor8888(gPixels[x+i + y_component]);
}
else {
temp_colour = kWhite;
}
colour += temp_colour * kMultiplier;
}
for ( int i = 1; i <= kBlurWidth; i++) {
float4 temp_colour;
if ( x + i < mImageWidth) {
temp_colour = rsUnpackColor8888(gPixels[x+i + y_component]);
}
else {
temp_colour = kWhite;
}
colour += temp_colour * kMultiplier;
}
colour.a = 1.0f;
*v_out = rsPackColorTo8888(colour);
}
void filter() {
mImageWidth = rsAllocationGetDimX(gIn);
rsDebug("Image size is ", rsAllocationGetDimX(gIn), rsAllocationGetDimY(gOut));
rsForEach(gScript, gIn, gOut, NULL);
}
从以下Java调用。请注意对mScript.bind_gPixels(mInAllocation)的调用,该调用将原始图像数据绑定到Renderscript中的gPixel指针,因此使图像数据可用作数组。
mRS = RenderScript.create(this);
mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());
mScript = new ScriptC_blur(mRS, getResources(), R.raw.blur);
mScript.bind_gPixels(mInAllocation);
mScript.set_gIn(mInAllocation);
mScript.set_gOut(mOutAllocation);
mScript.set_gScript(mScript);
mScript.invoke_filter();
mOutAllocation.copyTo(mBitmapOut);