从UIImage(照片库)中获取RGB数据的快速方法



我想获得一个数据数组,其中包含存储在iOS(ios8-sdk)上的照片库(ALAsset)中的图片的RGB表示。我已经尝试过这种方法:

  • 使用[ALSetRepresentation fullScreenImage]从ALAsset获取CGImage
  • 将CGImage绘制到CGContext

该方法有效,我得到了一个指向rgb数据的指针,但这非常慢(有2个转换)。最终目标是在OpenGL纹理中快速加载图像。

我从照片库获取图像的代码

ALAsset* currentPhotoAsset = (ALAsset*) [self.photoAssetList objectAtIndex:_currentPhotoAssetIndex];
ALAssetRepresentation *representation = [currentPhotoAsset defaultRepresentation];
//-> REALLY SLOW
UIImage *currentPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];

我在CGContext上绘制的代码:

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * textureWidth;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(textureData, textureWidth, textureHeight,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
//--> THAT'S REALLY SLOW
CGContextDrawImage(context, CGRectMake(0, 0, textureWidth, textureHeight), cgimage);
CGContextRelease(context);

你能做的不多,但如果你能找到办法,我很乐意听到。

问题是你需要解压缩图像(jpg,png…),这通常是通过创建一个CGImage来完成的(UIImage只是它的包装)。但是,不允许直接从CGImage获取数据指针,但需要复制它们(真正缓慢的绘制调用)。不过,如果目标大小和格式与源相同,则此操作应该非常快,因为数据应该或多或少地被简单地复制。另一方面,如果textureWidthtextureHeight不同,则需要对这些像素的图像维度进行插值,并且此函数可能会变慢几倍。

我看到的唯一方法是获得一些库来直接从文件中解压缩图像,并获得该图像的数据指针。但我在加载图像纹理(使用背景线程)时从未遇到过性能问题。

无论如何,如果你还没有做类似的事情,我使用它来获得图像大小,然后找到填充图像大小的POT(二次幂)宽度和高度。然后,我创建了一个具有POT维度的空纹理,并调用子图像将原始图像数据传递给纹理。我使用一个自定义纹理类来处理这个问题,该类还包含(生成)纹理坐标,以便将纹理的正确部分绘制到帧缓冲区。然后这个类被扩展为支持atlasing,这通常是您在处理许多图像(纹理)时想要做的。

我希望这些信息能在任何方面帮助你。。。

最新更新