在iOS如何快速转换为RGB24 BGR24? [英] On iOS how to quickly convert RGB24 to BGR24?

查看:1107
本文介绍了在iOS如何快速转换为RGB24 BGR24?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用 vImageConvert_RGB888toPlanar8 vImageConvert_Planar8toRGB888 从Accelerate.framework到RGB24转换为BGR24,但是当数据需要变换是非常大的,比如3M或4M,时间需要花费上,这是约10ms。因此,一些人知道一些足够快的想法。我的code是这样的:

   - (无效)transformRGBToBGR:(常量UINT8 *){PICT
rgb.data =(无效*)PICT;vImage_Error错误= vImageConvert_RGB888toPlanar8(安培; RGB,&安培,红色,和放大器;绿,和蓝光,kvImageNoFlags);
如果(错误!= kvImageNoError){
    的NSLog(@vImageConvert_RGB888toARGB8888错误);
}错误= vImageConvert_Planar8toRGB888(和蓝光,和放大器;绿色&安培,红色,和放大器; BGR,kvImageNoFlags);
如果(错误!= kvImageNoError){
    的NSLog(@vImagePermuteChannels_ARGB8888错误);
}免费的((无效*)PICT);
}


解决方案

随着RGB888ToPlanar8叫你分散的数据,然后再聚吧。这是非常,非常,非常糟糕。如果33%的内存开销是可以承受的,请尝试使用RGBA格式和重排的B / R字节原地。

如果您要保存33%的百分比,那么我可能会建议如下。遍历所有的像素,但只读的4字节的倍数(因为LCM(3,4)是12,也就是3双字)。

  uint8_t有* src_image分别;
uint8_t有* dst_image和;uint32_t的* SRC =(uint32_t的*)和src_image;
uint32_t的* DST =(uint32_t的*)dst_image和;uint32_t的V1,V2,V3;
uint32_t的NV1,NV2,NV3;
的for(int i = 0; I< num_pixels / 12;我++)
{
     //读取12个字节
     V1 = * SRC ++;
     V2 = * SRC ++;
     V3 = * SRC ++;
     中的像素//洗牌位
     // [R1 G1 B1 R2 | G2 B2 R3 G3 | B3 R4 G4 B4]
     NV1 = // [B1 G1 R1 B2]
      ((V1>→8)及为0xFF)| (V1&安培; 0x00FF0000)| ((V1>> 16)及为0xFF)| ((v2和GT;> 24)及为0xFF);
     NV2 = // [G2 R2 B3 G3]
       ...
     NV3 = // [R3 B4 G4 R4]
       ...
     //写12个字节
     * DST ++ = NV1;
     * DST ++ = NV2;
     * DST ++ = NV3;
}

更妙的是可以与NEON内在函数来完成。

请参阅此链接从ARM的网站看到24位交换是如何完成的。

在BGR到RGB可以就地就像这样:

 无效neon_asm_convert_BGR_TO_RGB(uint8_t有* IMG,INT numPixels24)
{
    // numPixels被除以24
    __asm​​__挥发性(
        0:\\ n
        #负载3交错64位暂存器:\\ n
        vld3.8 {D0,D1,D2},[%0] \\ n上
        #交换D0和D2 - R和B \\ N
        VSWP D0,D2 \\ n
        #3店64位暂存器:\\ n
        vst3.8 {D0,D1,D2},[%0]!\\ N
        潜艇%1%1,#1 \\ n
        BNE 0B \\ n
        :
        :R(IMG),R(numPixels24)
        R 4,R 5
     );
}

I use vImageConvert_RGB888toPlanar8 and vImageConvert_Planar8toRGB888 from Accelerate.framework to convert RGB24 to BGR24, but when the data need to transform is very big, such as 3M or 4M, the time need to spend on this is about 10ms. So some one know some fast enough idea?.My code like this:

- (void)transformRGBToBGR:(const UInt8 *)pict{
rgb.data = (void *)pict;

vImage_Error error = vImageConvert_RGB888toPlanar8(&rgb,&red,&green,&blue,kvImageNoFlags);
if (error != kvImageNoError) {
    NSLog(@"vImageConvert_RGB888toARGB8888 error");
}

error = vImageConvert_Planar8toRGB888(&blue,&green,&red,&bgr,kvImageNoFlags);
if (error != kvImageNoError) {
    NSLog(@"vImagePermuteChannels_ARGB8888 error");
}

free((void *)pict);
}

解决方案

With a RGB888ToPlanar8 call you scatter the data and then gather it once again. This is very-very-very bad. If the memory overhead of 33% is affordable, try using the RGBA format and permute the B/R bytes in-place.

If you want to save 33% percents, then I might suggest the following. Iterate all the pixels, but read only a multiple of 4 bytes (since lcm(3,4) is 12, that is 3 dwords).

uint8_t* src_image;
uint8_t* dst_image;

uint32_t* src = (uint32_t*)src_image;
uint32_t* dst = (uint32_t*)dst_image;

uint32_t v1, v2, v3;
uint32_t nv1, nv2, nv3;
for(int i = 0 ; i < num_pixels / 12 ; i++)
{
     // read 12 bytes
     v1 = *src++;
     v2 = *src++;
     v3 = *src++;
     // shuffle bits in the pixels
     // [R1 G1 B1 R2 | G2 B2 R3 G3 | B3 R4 G4 B4]
     nv1 = // [B1 G1 R1 B2]
      ((v1 >> 8) & 0xFF) | (v1 & 0x00FF0000) | ((v1 >> 16) & 0xFF) | ((v2 >> 24) & 0xFF);
     nv2 = // [G2 R2 B3 G3]
       ...
     nv3 = // [R3 B4 G4 R4]
       ...
     // write 12 bytes
     *dst++ = nv1;
     *dst++ = nv2;
     *dst++ = nv3;
}

Even better can be done with NEON intrinsics.

See this link from ARM's website to see how the 24-bit swapping is done.

The BGR-to-RGB can be done in-place like this:

void neon_asm_convert_BGR_TO_RGB(uint8_t* img, int numPixels24)
{
    // numPixels is divided by 24
    __asm__ volatile(
        "0:                \n"
        "# load 3 64-bit regs with interleave: \n"
        "vld3.8      {d0,d1,d2}, [%0]   \n"
        "# swap d0 and d2 - R and B\n"
        "vswp d0, d2   \n"
        "# store 3 64-bit regs: \n"
        "vst3.8      {d0,d1,d2}, [%0]!      \n"
        "subs        %1, %1, #1       \n"
        "bne         0b            \n"
        :
        : "r"(img), "r"(numPixels24)
        : "r4", "r5"
     );
}

这篇关于在iOS如何快速转换为RGB24 BGR24?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆