在24位阵列图像数据中转换和转置32位图像数据的byte []的最快方法?

时间:2016-02-02 15:31:23

标签: c# image pointers optimization unsafe

我想知道是否有人可以考虑更好的解决方案来做这些事情。

我有一个32位格式的原始位图数据(RGBA)

我需要通过消除alpha分量来转换以24位格式转置此数组。

此外,我需要通过对齐结果数组的第一部分中的红色成分,第一个1/3之后的绿色和2/3之后的蓝色来转换数据,因为我正在进行RLE压缩之后。

通过这种对齐,我有更好的压缩,因为更有可能在像素之间进行红色,绿色和蓝色组件对齐。

我使用不安全和固定的指针来做到这一点。我得到了像11ms这样的东西来处理8.3M的数组长度。它似乎很低,但我正在进行实时屏幕抓取,每个ms都在计算......

(我绕过了不安全和固定的字节*东西):

byte* actualpointeur = actual == (IntPtr)pd1 ? pd1 : pd2; // it s the pointer on my source 32bit array
// pd24b is a pointer to my reception array at the right size...
byte* redindexp = pd24b;
byte* greenindexp = pd24b+(datain24format.Length / 3);
byte* blueindexp = pd24b+((datain24format.Length / 3) * 2);
for (int i = 0; i < datalenght; i += 4, actualpointeur+=4, redindexp++, greenindexp++, blueindexp++)
{
    *redindexp= *(actualpointeur);
    *greenindexp = *(actualpointeur+1);
    *blueindexp = *(actualpointeur+2);
}

更新

我已经通过使用int *而不是字节*完成了hans的建议,并将循环反转为从end到0(再次比较为零更快) 它有点好(首先算法在~32000个刻度中完成,第二个在~31000个刻度中完成)

 // it s the pointer on my source 32bit array
 int* actualpointeur = actual == (IntPtr)pd1 ? (int*)pd1 + (datalenght / 4) - 1 : (int*)pd2 + (datalenght / 4) - 1; 

 // pd24b is a pointer to my reception array at the right size...
 byte* redindexp = (pd24b + (datain24format.Length / 3)) - 1;
 byte* greenindexp = (pd24b + (datain24format.Length / 3) * 2) - 1;
 byte* blueindexp = (pd24b + datain24format.Length) - 1;
 for (int i = datalenght - 1; i >= 0; i -= 4, actualpointeur--, redindexp--, greenindexp--, blueindexp--)
 {
       *redindexp = (byte)*(actualpointeur);
       *greenindexp = (byte)(*(actualpointeur) >> 8);
       *blueindexp = (byte)(*(actualpointeur) >> 16);
 }

更新2

循环展开16像素有PFM建议(没有数据长度测试)我现在得到5ms(~15000)这是一个很大的改进...超过16不再提供改进

我的新循环是:

for (int i = _DataLenght - 1; i >= 0; i -= 64,  actualpointeur-=16,redindexp-=16,greenindexp-=16,blueindexp-=16)
{
     *redindexp = (byte)*(actualpointeur);
     *greenindexp = (byte)(*(actualpointeur) >> 8);
     *blueindexp = (byte)(*(actualpointeur) >> 16);
     *(redindexp-1) = (byte)*(actualpointeur-1);
     *(greenindexp-1) = (byte)(*(actualpointeur-1) >> 8);
     *(blueindexp-1) = (byte)(*(actualpointeur-1) >> 16);
     ...
     *(redindexp - 15) = (byte)*(actualpointeur - 15);
     *(greenindexp - 15) = (byte)(*(actualpointeur - 15) >> 8);
     *(blueindexp - 15) = (byte)(*(actualpointeur - 15) >> 16);                                
}

我开始关注gpu ......

0 个答案:

没有答案