从JPEG-2000创建openGL纹理的快捷方法?

时间:2016-06-03 01:51:22

标签: ios objective-c opengl-es

我需要加载大型(500万像素)jpeg图像并从中创建openGL纹理。它们不是2的幂,不能为此应用程序预处理。装载非常慢,iPad Air 2上每张图像大约一秒钟。我需要加载十几个这样的图像,并尽可能快地为每个图像创建一个GL纹理。

分析显示了CGContextDrawImage的瓶颈。以前的答案表明这是一个常见的问题。

This previous answer似乎最相关,(不幸的是)并没有让我充满希望。我还没有尝试过lib-jpeg(在另一个答案中建议) - 试图保留第三方代码有几个原因。

但是 - 答案是2014年,事情发生了变化。有没有人知道从jpegs创建纹理的更快方法?通过更改CGContextDrawImage的参数(如在this answer中 - 我尝试了建议的更改而没有明显的速度变化)或完全使用不同的方法?

当前纹理创建块(异步调用):

UIImage *image = [UIImage imageWithData:jpegImageData];
if (image) {

    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture( GL_TEXTURE_2D, textureID);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

    GLsizei width = (GLsizei)CGImageGetWidth(image.CGImage);
    GLsizei height = (GLsizei)CGImageGetHeight(image.CGImage);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    void *imageData = malloc( height * width * 4 );
    CGContextRef imgcontext = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big );
    CGColorSpaceRelease( colorSpace );
    CGContextDrawImage( imgcontext, CGRectMake( 0, 0, width, height ), image.CGImage );

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
    CGContextRelease(imgcontext);
    free(imageData);

    // ... store the textureID for use by the caller
    // ...
}

(编辑添加)

我尝试过GLKTextureLoader。我一直得到一个nil返回值,错误是错误NSError * domain:“GLKTextureLoaderErrorDomain” - 代码:12。

我意识到我需要加载的JPEG是JPEG 2000;这可能是问题所在。我玩过GLKTextureLoader方法;我可以让它工作非J2K jpegs,但不是我需要加载的J2K。 (FWIW,我需要加载的文件打包在更大的文件中,因此我从文件中提取数据子范围,如下:

NSData *jpegImageData = [data subdataWithRange:NSMakeRange(offset, dataLength)];
GLKTextureInfo *jpegTexture;
NSError *theError;
jpegTexture = [GLKTextureLoader textureWithContentsOfData:jpegImageData options:nil error:&theError];

但是,如上所述,jpegImageData因上述错误而返回nil。这适用于小型jpeg,甚至使用subdataWithRange方法。

同样,

UIImage *image = [UIImage imageWithData:jpegImageData];
jpegTexture = [GLKTextureLoader textureWithCGImage:image.CGImage options:nil error:&theError];

以相同的“代码12”错误返回nil。

iOS Developer page (Table 1-1)表示仅在OS X上支持JPEG-2000,但在我尝试

CFArrayRef mySourceTypes = CGImageSourceCopyTypeIdentifiers(); CFShow(mySourceTypes);

显示支持格式的方法,JPEG-2000就在其中(在我的iOS设备上运行):

33 : <CFString 0x19d721bf8 [0x1a1da0150]>{contents = "public.jpeg-

有关在JPEG-2000上使用更快的GLKTextureLoader方法的建议吗?

1 个答案:

答案 0 :(得分:1)

您是否尝试过GLKit Framework method

    function removeDuplicates() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Form responses 2");
 var data = sheet.getDataRange().getValues();
  var newData = new Array();
  for(i in data){
    var row = data[i];
    var duplicate = false;
    for(j in newData){
      if( row[0] == newData[j][1] && row[1] == newData[j][3]){
  duplicate = true;
      }
    }
    if(!duplicate){
      newData.push(row);
    }
  }
  sheet.clearContents();
  sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
 }