Question

By decoder transform H264 video to rgb24 file, it can be displayer well on Windows, but when I use UIImage to display it on UIImageView its color is not right. The code I use as this:

- (UIImage *)imageFromAVPicture:(const UInt8 *)pict width:(int)width height:(int)height
{
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pict, width*height*3,kCFAllocatorNull);

    CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGImageRef cgImage = CGImageCreate(width, 
                                       height, 
                                       8,
                                       24, 
                                       width*3, 
                                       colorSpace, 
                                       bitmapInfo, 
                                       provider, 
                                       NULL, 
                                       YES, 
                                       kCGRenderingIntentDefault);

    CGColorSpaceRelease(colorSpace);

    UIImage *image = [self scaleImage:cgImage];
    //UIImage *image = [[UIImage alloc] initWithCGImage:cgImage];
    CGImageRelease(cgImage);
    CGDataProviderRelease(provider);
    CFRelease(data);

    return image;
}

But before create CGImage, add code as following, its show will be right, what following code do is transform betweent rgb and bgr.

UInt8 tmpBuff1,*tmpBuff2;
tmpBuff2 = (UInt8 *)pict;

for(int i =0;i<height;i++)
{
    for(int j=0;j<width;j++)
    {
        tmpBuff1 = *tmpBuff2;
        *tmpBuff2 = *(tmpBuff2+2);
        *(tmpBuff2+2) = tmpBuff1;
        tmpBuff2 += 3;
    }
}

After transform from rgb to bgr, its show will be right.

So I want to know why, why the same RGB24 file can play well on PC, but wrong on iOS before transform from RGB24 to BGR24.

Was it helpful?

Solution

This is a standard endianness issue. Which byte represents which color is not standardized for RGB. Windows uses R in the MSB and Mac/iOS uses R in the LSB. So you always need to do the byte order transform you showed when moving RGB between Windows and Mac/iOS. Note that you will likely find it more efficient to use the Accelerate framework's vImagePermuteChannels_ARGB8888 to do this type of transform instead of writing your own code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top