How to create a ARGB CGImageRef from a ABGR CGImageRef in Cocoa


Ever since I got the video feed working on my Packbot OCU application the reds and the blues have been swapped, giving the video feed a weird spacey look and totally cramping my style. Apparently the data is sent this way because leaving it in BGR format reduces the load for the Packbot's onboard computer. In other languages correcting this problem is a simple task, all you have to do is get the raw data and swap the red and blue components for each pixel. However I wasn't exactly clear how to retrieve the raw image data from a CGImageRef based on the Apple documentation. Using some creative search terms in Google this weekend I was able to piece together what I needed to get a proper ARGB image. The following code may not be the best way to do this, but it definitely works.
 

 

 

- (CGImageRef) CreateARGBImageWithABGRImage: (CGImageRef) abgrImageRef {

// the data retrieved from the image ref has 4 bytes per pixel (ABGR).

CFDataRef abgrData = CGDataProviderCopyData(CGImageGetDataProvider(abgrImageRef));

UInt8 *pixelData = (UInt8 *) CFDataGetBytePtr(abgrData);

int length = CFDataGetLength(abgrData);

 

// abgr to rgba

// swap the blue and red components for each pixel...

UInt8 tmpByte = 0;

for (int index = 0; index < length; index+= 4) {

tmpByte = pixelData[index + 1];

pixelData[index + 1] = pixelData[index + 3];

pixelData[index + 3] = tmpByte;

}

 

// grab the bgra image info

size_t width = CGImageGetWidth(abgrImageRef);

size_t height = CGImageGetHeight(abgrImageRef);

size_t bitsPerComponent = CGImageGetBitsPerComponent(abgrImageRef);

size_t bitsPerPixel = CGImageGetBitsPerPixel(abgrImageRef);

size_t bytesPerRow = CGImageGetBytesPerRow(abgrImageRef);

CGColorSpaceRef colorspace = CGImageGetColorSpace(abgrImageRef);

CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(abgrImageRef);

 

// create the argb image

CFDataRef argbData = CFDataCreate(NULL, pixelData, length);

CGDataProviderRef provider = CGDataProviderCreateWithCFData(argbData);

CGImageRef argbImageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, 

colorspace, bitmapInfo, provider, NULLtruekCGRenderingIntentDefault);

 

// release what we can

CFRelease(abgrData);

CFRelease(argbData);

CGDataProviderRelease(provider);

 

// return the pretty new image

return argbImageRef;

}

 

 

So there you have it. I hope this helps someone else. Suggestions for improvements on this are certainly welcome.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM