0

iOSアプリのpng画像アセットからARGBピクセルデータを読み取ろうとしています。ここで説明するように、CGDataProviderを使用してCFDataRefを取得しています。

http://developer.apple.com/library/ios/#qa/qa1509/_index.html

特定の画像で初めて使用したときに完全に機能します。しかし、同じ画像で2回目に使用すると、長さ0のCFDataRefが返されます。

多分私は何かをリリースしていませんか?なぜそれをするのでしょうか?

- (GLuint)initWithCGImage:(CGImageRef)newImageSource
{
    CGDataProviderRef dataProvider;
    CFDataRef dataRef;

    GLuint t;

    @try {
 //   NSLog(@"initWithCGImage");
 //   report_memory2();
    CGFloat widthOfImage = CGImageGetWidth(newImageSource);
    CGFloat heightOfImage = CGImageGetHeight(newImageSource);
    //    pixelSizeOfImage = CGSizeMake(widthOfImage, heightOfImage);
    //    CGSize pixelSizeToUseForTexture = pixelSizeOfImage;

    //    CGSize scaledImageSizeToFitOnGPU = [GPUImageOpenGLESContext sizeThatFitsWithinATextureForSize:pixelSizeOfImage];

    GLubyte *imageData = NULL;
    //CFDataRef dataFromImageDataProvider;


   // stbi stbiClass;
    int x;
    int y;
    int comp;

    dataProvider = CGImageGetDataProvider(newImageSource);
    dataRef = CGDataProviderCopyData(dataProvider);

    const unsigned char * bytesRef = CFDataGetBytePtr(dataRef);
   // NSUInteger length = CFDataGetLength(dataRef);

    //CGDataProviderRelease(dataProvider);
    //dataProvider = nil;
    /*
    UIImage *tmpImage = [UIImage imageWithCGImage:newImageSource];

    NSData *data2 =         UIImagePNGRepresentation(tmpImage);
//    if (data2==NULL)
//        data2 =        UIImageJPEGRepresentation(tmpImage, 1);

    unsigned char *bytes = (unsigned char *)[data2 bytes];
    NSUInteger length = [data2 length];*/
//    stbiClass.img_buffer = bytes;
//    stbiClass.buflen = length;
//    stbiClass.img_buffer_original = bytes;
//    stbiClass.img_buffer_end = bytes + length;

//    unsigned char *data = stbi_load_main(&stbiClass, &x, &y, &comp, 0);
    //unsigned char * data = bytesRef;
    x = widthOfImage;
    y = heightOfImage;
    comp = CGImageGetBitsPerPixel(newImageSource)/8;

    int textureWidth = [self CalcPow2: x];
    int textureHeight = [self CalcPow2: y];

    unsigned char *scaledData = [self scaleImageWithParams:@{@"x":@(x), @"y":@(y), @"comp":@(comp), @"targetX":@(textureWidth), @"targetY":@(textureHeight)} andData:(unsigned char *)bytesRef];
    //CFRelease (dataRef);
   // dataRef = nil;
 //    free (data);

    glGenTextures(1, &t);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, t);
    GLint format  = (comp > 3) ? GL_RGBA : GL_RGB;


    imageData = scaledData;

    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);
    glTexImage2D(GL_TEXTURE_2D, 0, format, textureWidth, textureHeight, 0, format, GL_UNSIGNED_BYTE, imageData);
    //GLenum err = glGetError();
    }
    @finally
    {
        CGDataProviderRelease(dataProvider);
//        CGColorSpaceRelease(colorSpaceRef);
        CGImageRelease(dataRef);
    }


    return t;
}

これが最初と同じパスを持つ[UIimageimageNamed:Path]から発生するCGImageRefで2回目に呼び出されると、長さ0のdataRefを取得します。ただし、最初は機能します。

4

1 に答える 1

1

投稿したコードに大きな問題が 1 つ見つかり、修正しました。まず第一に、同じ画像を 2 回読み込まなくても、複数の画像を読み込んでもクラッシュしていました。この問題はメモリに関連しているため、あらゆる種類の奇妙な方法で失敗しました。

コードの問題は、「CGDataProviderRelease(dataProvider);」と呼んでいることです。newImageSource のデータ プロバイダーを使用していますが、このデータ プロバイダーを作成していません。だからと言って手放してはいけません。それらを作成、保持、またはコピーした場合にのみ、物をリリースする必要があります。

それとは別に、メモリ不足のためにアプリがクラッシュすることもありましたが、これを修正した後、できるだけ早く割り当てて解放する「エコノミー」タイプを使用することができました。

現在、この特定のコードに他に問題はありません。

于 2012-12-18T18:18:01.993 に答える