largeimagedownsizing giving destImageRef NULL and crashing ios

171 views Asked by At

I am using Apple sample code to downsize the image.
I tested for two images. One image is 204kB and other image is 205kB. It is crashing for 204kB image giving error as Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan nan]'
I got the code from https://developer.apple.com/library/ios/samplecode/LargeImageDownsizing/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011173

Link for the image which is crashing http://www.bluebell-railway.co.uk/bluebell/personal/jon-bowers/extension/17_3l.jpg

I could only get that destImageRef is coming NULL

Code to downsize the image:

-(void)downsize:(id)_arg {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

sourceImage = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kImageFilename ofType:nil]];
if( sourceImage == nil ) NSLog(@"input image not found!");

sourceResolution.width = CGImageGetWidth(sourceImage.CGImage);
sourceResolution.height = CGImageGetHeight(sourceImage.CGImage);

sourceTotalPixels = sourceResolution.width * sourceResolution.height;

sourceTotalMB = sourceTotalPixels / pixelsPerMB;

imageScale = destTotalPixels / sourceTotalPixels;

destResolution.width = (int)( sourceResolution.width * imageScale );
destResolution.height = (int)( sourceResolution.height * imageScale );

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
int bytesPerRow = bytesPerPixel * destResolution.width;

void* destBitmapData = malloc( bytesPerRow * destResolution.height );
if( destBitmapData == NULL ) NSLog(@"failed to allocate space for the output image!");

destContext = CGBitmapContextCreate( destBitmapData, destResolution.width, destResolution.height, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast );

if( destContext == NULL ) {
    free( destBitmapData ); 
    NSLog(@"failed to create the output bitmap context!");
}        

CGColorSpaceRelease( colorSpace );

CGContextTranslateCTM( destContext, 0.0f, destResolution.height );
CGContextScaleCTM( destContext, 1.0f, -1.0f );

sourceTile.size.height = (int)( tileTotalPixels / sourceTile.size.width );     
NSLog(@"source tile size: %f x %f",sourceTile.size.width, sourceTile.size.height);
sourceTile.origin.x = 0.0f;

destTile.size.width = destResolution.width;
destTile.size.height = sourceTile.size.height * imageScale;        
destTile.origin.x = 0.0f;
NSLog(@"dest tile size: %f x %f",destTile.size.width, destTile.size.height);

sourceSeemOverlap = (int)( ( destSeemOverlap / destResolution.height ) * sourceResolution.height );
NSLog(@"dest seem overlap: %f, source seem overlap: %f",destSeemOverlap, sourceSeemOverlap);    
CGImageRef sourceTileImageRef;

int iterations = (int)( sourceResolution.height / sourceTile.size.height );

int remainder = (int)sourceResolution.height % (int)sourceTile.size.height;
if( remainder ) iterations++;

float sourceTileHeightMinusOverlap = sourceTile.size.height;
sourceTile.size.height += sourceSeemOverlap;
destTile.size.height += destSeemOverlap;    
NSLog(@"beginning downsize. iterations: %d, tile height: %f, remainder height: %d", iterations, sourceTile.size.height,remainder );
for( int y = 0; y < iterations; ++y ) {

    NSAutoreleasePool* pool2 = [[NSAutoreleasePool alloc] init];
    NSLog(@"iteration %d of %d",y+1,iterations);
    sourceTile.origin.y = y * sourceTileHeightMinusOverlap + sourceSeemOverlap; 
    destTile.origin.y = ( destResolution.height ) - ( ( y + 1 ) * sourceTileHeightMinusOverlap * imageScale + destSeemOverlap ); 

    sourceTileImageRef = CGImageCreateWithImageInRect( sourceImage.CGImage, sourceTile );

    if( y == iterations - 1 && remainder ) {
        float dify = destTile.size.height;
        destTile.size.height = CGImageGetHeight( sourceTileImageRef ) * imageScale;
        dify -= destTile.size.height;
        destTile.origin.y += dify;
    }

    CGContextDrawImage( destContext, destTile, sourceTileImageRef );

    CGImageRelease( sourceTileImageRef ); 

    [sourceImage release];
    // free all objects that were sent -autorelease within the scope of this loop.
    [pool2 drain];     
    if( y < iterations - 1 ) {            
        sourceImage = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kImageFilename ofType:nil]];
        [self performSelectorOnMainThread:@selector(updateScrollView:) withObject:nil waitUntilDone:YES];
    }
}
NSLog(@"downsize complete.");
[self performSelectorOnMainThread:@selector(initializeScrollView:) withObject:nil waitUntilDone:YES];
CGContextRelease( destContext );
[pool drain];    

and in the following method it is giving "destImageRef is null"

    -(void)createImageFromContext {
    // create a CGImage from the offscreen image context
    CGImageRef destImageRef = CGBitmapContextCreateImage( destContext );
    if( destImageRef == NULL ) NSLog(@"destImageRef is null.");
    // wrap a UIImage around the CGImage
    self.destImage = [UIImage imageWithCGImage:destImageRef scale:1.0f orientation:UIImageOrientationDownMirrored];
    // release ownership of the CGImage, since destImage retains ownership of the object now.
    CGImageRelease( destImageRef );
    if( destImage == nil ) NSLog(@"destImage is nil.");
}
0

There are 0 answers