我正在将RGBA图像转换为RGB。使用天真数组副本:
for (int j=0, i=0; i<argbBytes.length; i++){
if (i%4 < 3) {
thumbRGB888[j++] = argbBytes[i];
}
}
但是,正如预期的那样,它是超慢的(与System.arraycopy()方法相比),尤其是在Android设备上。有没有一个技巧可以更快地完成它?
答案 0 :(得分:3)
使用两个索引和System.arraycopy()
,每次复制3个元素:
for (int i = 0, j = 0; i < argbBytes.length; i += 4, j += 3)
{
System.arraycopy(argbBytes, i, thumbRGB888, j, 3);
}
应该明显更快。它不仅摆脱了模数和比较,System.arraycopy()
是用本机代码实现的,依赖于memcpy
,它比单个赋值更快。
答案 1 :(得分:0)
而不是
if (i%4 < 3)
DO
for (int j=0, i=0; i<argbBytes.length; i++){
thumbRGB888[j++] = argbBytes[i++];
thumbRGB888[j++] = argbBytes[i++];
thumbRGB888[j++] = argbBytes[i++];
}
这个解决方案要快得多,因为模运算和比较成本更高。
答案 2 :(得分:0)
你应该避免使用if
语句,它会进行2次操作
从i = 0开始,i%4&lt; 3表示:0,1,2,4,5,6,8,9,10。
我就是这样做的:
int div = 4;
int n = argbBytes.length - argbBytes.length%div;
int i=0;
int j=0;
for (; i<n; i+=div){
// i = 0, 4, 8 ... then i, i+1,i+2 should pass (i%4<3)
thumbRGB888[j++] = argbBytes[i];
thumbRGB888[j++] = argbBytes[i+1];
thumbRGB888[j++] = argbBytes[i+2];
}
for(;i<argbBytes.length;i++){
//i=n,n+1,n+2, since n%4==0 then (i%4<3) is passed
thumbRGB888[j++] = argbBytes[i];
}
- &GT; i
的增量是相同的
用[0,1,2,3,4,5,6,7,8,9,10]测试返回[0,1,2,4,5,6,8,9,10]
使用10,000,000个元素的数组进行测试,以30的循环运行
原码:3191ms
修改代码:1653ms
我已经在C#中测试过,所以结果可能会有所不同。顺便说一句,这可能不是一个很大的改进。
答案 3 :(得分:0)
不是定义明确的答案,而是指针: 从未完成,并且不完全满足您的请求,但请将转换保留为BitmapFactory。完全不确定,但是:
使用BitmapFactory从字节中获取ARGB位图。如果不可变,那么可能没有新的分配。也可能是,您首先需要将字节包装到缓冲区中。
然后Bitmap.copy
应该是可能的。
一些疯狂的想法:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inMutable = true; // Bitmap generated mutable.
opts.inPreferredConfig = Bitmap.Config.ARGB_8888; // I hope not BGRA.
Bitmap bmARGB = BitmapFactory.decodeByteArray(argbBytes, 0, argbBytes.length,
opts);
bmARGB.setHasAlpha(false);
DisplayMetrics display = ...;
int[] colors = null; // Palette
Bitmap bmRGB = bmARBG.createBitmap(display, colors, width, height,
Bitmap.Config.RGB_565); // 16 bit colors only!
bmARGB.recycle();