6 android renderscript android-renderscript
我正在尝试使用Android的RenderScript在图像后面渲染一个半透明的圆圈,但是从RenderScript内核返回一个值时出了问题.
这是我的内核:
#pragma version(1)
#pragma rs java_package_name(be.abyx.aurora)
// We don't need very high precision floating points
#pragma rs_fp_relaxed
// Center position of the circle
int centerX = 0;
int centerY = 0;
// Radius of the circle
int radius = 0;
// Destination colour of the background can be set here.
float destinationR;
float destinationG;
float destinationB;
float destinationA;
static int square(int input) {
return input * input;
}
uchar4 RS_KERNEL circleRender(uchar4 in, uint32_t x, uint32_t y) {
//Convert input uchar4 to float4
float4 f4 = rsUnpackColor8888(in);
// Check if the current coordinates fall inside the circle
if (square(x - centerX) + square(y - centerY) < square(radius)) {
// Check if current position is transparent, we then need to add the background!)
if (f4.a == 0) {
uchar4 temp = rsPackColorTo8888(0.686f, 0.686f, 0.686f, 0.561f);
return temp;
}
}
return rsPackColorTo8888(f4);
}
Run Code Online (Sandbox Code Playgroud)
现在,该rsPackColorTo8888()函数需要4个浮点数,其值介于0.0和1.0之间.然后通过计算每个浮点值的255倍来找到所得到的ARGB颜色.因此给定的浮点数对应于颜色R = 0.686*255 = 175,G = 0.686*255 = 175,B = 0.686*255 = 175且A = 0.561*255 = 143.
该rsPackColorTo8888()函数本身工作正常,但是当发现uchar4值从内核返回,一些真正怪异的发生.R,G和B值分别变为红色*α= 56,绿色*α= 56和蓝色*α= 56,其中Alpha为0.561.这意味着R,G和B的值不能大于A = 0.561*255.
手动设置输出而不是使用rsPackColorTo8888()产生完全相同的行为.我的意思是下面的代码产生完全相同的结果,这反过来证明这rsPackColorTo8888()不是问题:
if (square(x - centerX) + square(y - centerY) < square(radius)) {
// Check if current position is transparent, we then need to add the background!)
if (f4.a == 0) {
uchar4 temp;
temp[0] = 175;
temp[1] = 175;
temp[2] = 175;
temp[3] = 143;
return temp;
}
}
Run Code Online (Sandbox Code Playgroud)
这是调用脚本的Java代码:
@Override
public Bitmap renderParallel(Bitmap input, int backgroundColour, int padding) {
ResizeUtility resizeUtility = new ResizeUtility();
// We want to end up with a square Bitmap with some padding applied to it, so we use the
// the length of the largest dimension (width or height) as the width of our square.
int dimension = resizeUtility.getLargestDimension(input.getWidth(), input.getHeight()) + 2 * padding;
Bitmap output = resizeUtility.createSquareBitmapWithPadding(input, padding);
output.setHasAlpha(true);
RenderScript rs = RenderScript.create(this.context);
Allocation inputAlloc = Allocation.createFromBitmap(rs, output);
Type t = inputAlloc.getType();
Allocation outputAlloc = Allocation.createTyped(rs, t);
ScriptC_circle_render circleRenderer = new ScriptC_circle_render(rs);
circleRenderer.set_centerX(dimension / 2);
circleRenderer.set_centerY(dimension / 2);
circleRenderer.set_radius(dimension / 2);
circleRenderer.set_destinationA(((float) Color.alpha(backgroundColour)) / 255.0f);
circleRenderer.set_destinationR(((float) Color.red(backgroundColour)) / 255.0f);
circleRenderer.set_destinationG(((float) Color.green(backgroundColour)) / 255.0f);
circleRenderer.set_destinationB(((float) Color.blue(backgroundColour)) / 255.0f);
circleRenderer.forEach_circleRender(inputAlloc, outputAlloc);
outputAlloc.copyTo(output);
inputAlloc.destroy();
outputAlloc.destroy();
circleRenderer.destroy();
rs.destroy();
return output;
}
Run Code Online (Sandbox Code Playgroud)
当alpha设置为255(或1.0作为浮点数)时,返回的颜色值(在我的应用程序的Java代码中)是正确的.
我做错了什么,或者这真的是RenderScript实现中的某个错误?
注意:我已经在Oneplus 3T(Android 7.1.1),Nexus 5(Android 7.1.2),Android模拟器版本7.1.2和6.0上检查并验证了此行为
小智 0
而不是使用类型传递值:
uchar4 temp = rsPackColorTo8888(0.686f, 0.686f, 0.686f, 0.561f);
Run Code Online (Sandbox Code Playgroud)
尝试创建一个 float4 并传递它。
float4 newFloat4 = { 0.686, 0.686, 0.686, 0.561 };
uchar4 temp = rsPackColorTo8888(newFloat4);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
184 次 |
| 最近记录: |