iOS 转换BGR24 为 RGB24
為了適應多平臺,也是滿足跨平臺的要求,有時候必須轉換。因為rgb像素在windows上是按照BGRBGR這樣的順序存儲的,而在OS X上則是按照RGBRGB存儲。所以如果不做轉換,必然在某個平臺上出現色差。這里主要演示如何在OS X上實現這種轉換。
1.第一種方法最為簡單也最慢,就是寫一個循環,交換R和B的位置。
Uint8 tmpValue = 0; for(int i = 0; i < numOfPixels; i+=3) {tmpValue = pixelBuffer[i];pixelBuffer[i] = pixelBuffer[i + 2];pixelBuffer[i + 2] = tmpValue; }2.第二種相當快了,使用accelerate.framwork,不過一個較大的限制是最低系統版本要求iOS5,所以使用范圍受到了限制。但是不考慮兼容性的話性能提升還是很厲害的。
- (void)transformRGBToBGR:(const UInt8 *)pict {rgb.data = (void *)pict;vImage_Error error = vImageConvert_RGB888toPlanar8(&rgb,&red,&green,&blue,kvImageNoFlags);if (error != kvImageNoError) {NSLog(@"vImageConvert_RGB888toPlanar8 error");}error = vImageConvert_Planar8toRGB888(&blue,&green,&red,&bgr,kvImageNoFlags);if (error != kvImageNoError) {NSLog(@"vImageConvert_Planar8toRGB888 error");}free((void *)pict);}這里首先將內存分布為BGR的數據轉換為平面數據,需要三個同原始圖像一樣寬高的緩沖區存儲解析出的R/G/B數據,接下來就可以使用vImageConvert_Planar8toRGB888隨意重組他們的順序,當然要合理,如果你胡亂重組排序的,整合出來的圖像肯定是不對的。
由于vImageConvert_Planar8toRGB888和vImageConvert_RGB888toPlanar8都是使用neon匯編優化過的,所以速度很快,幾乎已經達到極限了。但是仔細觀察,可能就會發現,這種方式需要同樣大小的較多的額外存儲,尤其是這種函數作為核心函數被調用的次數相當高,導致頻繁的分配和釋放內存,因而造成內存碎片,影響系統系能。因此,這里就引出了終極解決方案。
3.最快的且節能內存的就是這種方法了,即直接使用neon匯編編寫,而不是調用第三方的函數來完成。當數據量較大時,頻繁的復制和移動數據廢除耗時,而這種方案就可以避免這個問題。相比第二種方法,這種方法節約了2ms,你可能會說,看上去并不是很明顯??墒钱斈懔私饬薈PU的主頻也就900MHZ時,你就知道提升不小了。
- (void) neon_asm_convert_BGR_TO_RGB:(UInt8 *) img numPixel:(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"); }第三種解決方案引自http://stackoverflow.com/questions/11683864/on-ios-how-to-quickly-convert-rgb24-to-bgr24
轉載于:https://www.cnblogs.com/CoderPlace/archive/2012/07/30/2615793.html
總結
以上是生活随笔為你收集整理的iOS 转换BGR24 为 RGB24的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ruby表达式
- 下一篇: 阿里云盘内测_阿里云盘内测邀请码发放