这是我实现BoxBlur的renderscript代码:
#pragma version(1)
#pragma rs java_package_name(com.karthik.imgproc)
rs_allocation pixelAlloc;
rs_allocation indices;
uint width;
uint height;
int radius;
void root(const uint *v_in, uchar4 *v_out) {
uint row = *v_in >> 16 & 0xffff;
uint col = *v_in & 0xffff;
uint sumR = 0;
uint sumG = 0;
uint sumB = 0;
int yr = 0;
int xr = 0;
for(yr = -radius; yr <= radius; yr++){
for(xr = -radius; xr <= radius; xr++){
int a = row + xr;
int b = col + yr;
if(a < 0 || b < 0)
continue;
uchar4 p = rsGetElementAt_uchar4(pixelAlloc, a, b);
sumR = sumR + p.r;
sumG = sumG + p.g;
sumB = sumB + p.b;
}
}
uint divisor = ((radius * 2) + 1) * ((radius * 2) + 1);
float R = sumR / divisor;
float G = sumG / divisor;
float B = sumB / divisor;
float A = rsGetElementAt_uchar4(pixelAlloc, row, col).a;
if(R > 255)
R = 255;
if(R < 0)
R = 0;
if(G > 255)
G = 255;
if(G < 0)
G = 0;
if(B > 255)
B = 255;
if(B < 0)
B = 0;
R = R/255;
G = G/255;
B = B/255;
A = A/255;
*v_out = rsPackColorTo8888(R,G,B,A);
}
这是启动renderscript代码执行的java代码
private void convolve(final Bitmap srcBmp, int radius){
int width = srcBmp.getWidth();
int height = srcBmp.getHeight();
Allocation inPixels = Allocation.createFromBitmap(mRs, srcBmp, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SHARED);
inPixels.copyFrom(srcBmp);
ScriptC_convolve script = new ScriptC_convolve(mRs);
script.set_width(width);
script.set_height(height);
script.set_radius(radius);
script.set_pixelAlloc(inPixels);
Allocation in = Allocation.createTyped(mRs, Type.createXY(mRs, Element.U32(mRs), srcBmp.getWidth(), srcBmp.getHeight()), Allocation.USAGE_SCRIPT);
int pixelIndices[] = new int[srcBmp.getWidth() * srcBmp.getHeight()];
int i = 0;
for(int col=0; col<width; col++){
for(int row=0; row<height; row++, i++){
pixelIndices[i] = (row << 16) | col ;
}
}
in.copy2DRangeFrom(0, 0, srcBmp.getWidth(), srcBmp.getHeight(), pixelIndices);
final Bitmap dstBitmap = Bitmap.createBitmap(srcBmp.getWidth(), srcBmp.getHeight(), srcBmp.getConfig());
Allocation out = Allocation.createTyped(mRs, inPixels.getType(), Allocation.USAGE_SHARED);
script.forEach_root(in, out);
out.copyTo(dstBitmap);
((ImageView)findViewById(R.id.dstImgView)).setImageDrawable(new BitmapDrawable(getResources(), dstBitmap));
script.destroy();
}
问题是应用程序每次都有以下日志崩溃:
F/libc (28885): Fatal signal 7 (SIGBUS), code 2, fault addr 0xa3369000 in tid 28922 (imageprocessing)
F/libc (28885): Fatal signal 7 (SIGBUS), code 2, fault addr 0xa3369820 in tid 28920 (imageprocessing)
F/libc (28885): Fatal signal 7 (SIGBUS), code 2, fault addr 0xa336da20 in tid 28921 (imageprocessing)
I/DEBUG (15097): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG (15097): Build fingerprint: 'motorola/falcon_asia_ds/falcon_umtsds:5.0.2/LXB22.46-28/30:user/release-keys'
I/DEBUG (15097): Revision: 'p3c0'
I/DEBUG (15097): ABI: 'arm'
I/DEBUG (15097): pid: 28885, tid: 28922, name: imageprocessing >>> imageeffect.kpbird.com.imageprocessing <<<
I/DEBUG (15097): signal 7 (SIGBUS), code 2 (BUS_ADRERR), fault addr 0xa3369000
I/DEBUG (15097): r0 00000001 r1 a320f020 r2 000001f7 r3 a2c27000
I/DEBUG (15097): r4 00159fe0 r5 00000b00 r6 00000000 r7 000000b7
I/DEBUG (15097): r8 00000000 r9 00000000 sl 00000001 fp 000000b8
I/DEBUG (15097): ip 00000000 sp a682dc94 lr ffffffff pc a2c230fc cpsr 200f0010
I/DEBUG (15097):
I/DEBUG (15097): backtrace:
I/DEBUG (15097): #00 pc 000000fc /dev/kgsl-3d0
I/DEBUG (15097): #01 pc fffffffd <unknown>
I/DEBUG (15097):
I/DEBUG (15097): Tombstone written to: /data/tombstones/tombstone_07
E/ (15097): tid 28920 does not exist in pid 28885. ignoring debug request
E/ (15097): tid 28921 does not exist in pid 28885. ignoring debug request
I/BootReceiver( 988): Copying /data/tombstones/tombstone_07 to DropBox (SYSTEM_TOMBSTONE)
W/ActivityManager( 988): Force finishing activity imageeffect.kpbird.com.imageprocessing/com.karthik.imgproc.MainActivity
I/WindowState( 988): WIN DEATH: Window{18f03389 u0 imageeffect.kpbird.com.imageprocessing/com.karthik.imgproc.MainActivity}
我不明白应用程序崩溃的原因。但对于非常小的图像说25x25分辨率,它的工作正常。这里有趣的观察是我评论出来的时候 * v_out = rsPackColorTo8888(R,G,B,A)在renderscript代码中,应用程序没有崩溃当然不会显示任何内容。我的问题是为什么它会在rsPackColorTo8888(R,G,B,A)崩溃?我实施的方式有什么问题。为什么它适用于非常小的图像?对于大多数图像应用程序崩溃。
答案 0 :(得分:2)
此代码存在许多问题。建议:
if(a < 0 || b < 0)
仅检查下限),float R = sumR / divisor;
)clamp()
而不是检查RGB值对0和255,第一个问题可能导致崩溃。第二个 - 介绍视觉工件。其余的东西减慢了。
答案 1 :(得分:0)
@Laubzega
感谢您的线索!最后我得到了解决方案除了你的第一点,即检查上限,我还应该更改java中的代码以正确发送(x,y)像素位置,如下所示:
for(int y=0; y < height; y++){
for(int x=0; x < width; x++, i++){
pixelIndices[i] = (x << 16) | y ;
}
}
现在应用程序正常运行而没有任何崩溃!!