CGDataProvider works the first time, returns an empty image the second time

回眸只為那壹抹淺笑 提交于 2019-12-11 17:47:57

问题


I am trying to read the ARGB pixel data from a png image asset in my ios App. I am using CGDataProvider to get a CFDataRef as described here:

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

It works perfectly the first time I use it on a certain image. But the second time I use it on THE SAME image, it returns a length 0 CFDataRef.

Maybe I am not releasing something? Why would it do that?

- (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;
}

The second time this is called on a CGImageRef that originate from a [UIimage imageNamed: Path] with the same Path as the first time, I get a dataRef of length 0. It works the first time though.


回答1:


I have found one big issue with the code I posted and fixed it. First of all, I was getting crashs even if I didn't load the same image twice, but rather more images. Since the issue is related to memory it failed in all sort of weird ways.

The issue with the code is that I am calling: "CGDataProviderRelease(dataProvider);" I am using the data provider of newImageSource, but I didn't create this dataprovider. That is why I shouldn't release it. You need to release things only if you created, retained or copied them.

Apart from that my App crash sometime due to low memory, but after fixing this I was able to use the "economy" type where I allocate and release as soon as possible.

Currently I can't see anything else wrong with this specific code.



来源:https://stackoverflow.com/questions/13922233/cgdataprovider-works-the-first-time-returns-an-empty-image-the-second-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!