What I am doing is on every touch event I am creating an image from unsigned char *. Here is my function
-(void)paint:(ImageWarper::WarpedImage *)warpedImg isCircleRequired:(bool)doDrawCircle atPoint:(CGPoint)pt{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if(!mWarper)
return;
unsigned char *pixelData = warpedImg->Image.Data;
int imageHeight = warpedImg->Image.Height;
int scanWidth = warpedImg->Image.ScanWidth;
int imageWidth = warpedImg->Image.Width;
CGDataProviderRef provider = CGDataProviderCreateWithData(
NULL,
pixelData,
imageHeight * scanWidth,
(CGDataProviderReleaseDataCallback)&freeRawData);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
int bytesPerPixel = warpedImg->Image.Bpp;
CGImageRef imageRef = CGImageCreate(imageWidth,
imageHeight,
BitsPerComponent,
bytesPerPixel * BitsPerComponent,
scanWidth,
colorSpaceRef,
bitmapInfo,
provider,
NULL,
YES,
renderingIntent);
if(!imageRef)
return;
UIImage *uiImage = [UIImage imageWithCGImage:imageRef];
imgScrollView.imgView.image = uiImage;
UIGraphicsBeginImageContext(mbmpImage.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 1.5);
CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
[mbmpImage drawInRect:CGRectMake(0, 0, mbmpImage.size.width, mbmpImage.size.height)];
[uiImage drawInRect:CGRectMake(warpedImg->Position.X, warpedImg->Position.Y, warpedImg->Image.Width, warpedImg->Image.Height)];
if(doDrawCircle){
[mbmpImage release];
mbmpImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
CGContextStrokeEllipseInRect(ctx,CGRectMake(pt.x - mRadius, pt.y - mRadius, mRadius*2, mRadius*2));
}
else{
[mbmpImage release];
mbmpImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
}
UIImage * resultingImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();
imgScrollView.imgView.image = resultingImage ;
if(!doDrawCircle) {
[mbmpImage release];
mbmpImage = [resultingImage retain];
}
if(doDrawCircle){
CGPoint pt2 = [self.view convertPoint:pt fromView:imgScrollView];
imgPreview.hidden = NO;
[self addText:mbmpImage text: @"+" atPoint:pt atRect:(warpedImg->Position.X, warpedImg->Position.Y, warpedImg->Image.Width, warpedImg->Image.Height)];
}
else{
[popoverController dismissPopoverAnimated:YES];
}
[resultingImage release];
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);
CGImageRelease(imageRef);
[pool drain];
}
This Function is called as follows:
NSMutableDictionary *d = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSValue valueWithPointer:wp1],@"warper", @"YES",@"isCircleRequired",
[NSValue valueWithCGPoint:location],@"point",nil];
[self performSelector:@selector(paintDic:) withObject:d];
[d release];
wp1 = nil;
-(void)paintDic:(NSMutableDictionary *)dictionary{
ImageWarper::WarpedImage *wp1 = (ImageWarper::WarpedImage *)[[dictionary objectForKey:@"warper"] pointerValue];
[self paint:wp1
isCircleRequired:[dictionary objectForKey:@"isCircleRequired"]
atPoint:[[dictionary objectForKey:@"point"] CGPointValue]];
}
I am using following callback function to release data.
void freeRawData(void *info, const void *data, size_t size) {
data = nil;
}
Can any one help me how do I optimize the speed of this. It is working fine on new iphone but not older iphones.
I am calling paint in perform selector so that I dont get hold of execution while it completes its creation of images.
Also any help to create images directly from raw data i.e. unsigned char * will be appreciated.
Before you attempt any optimizations, measure where you spend your time. Instruments’ performance tools will help you here.
Off the top of my head, I see a bit of stuff that really need not be there in the code you showed:
staticvariable might shave some time off this code.UIImages but usingCGContextDrawImageinstead might save you quite some time, too.dispatch_asyncinstead ofperformSelector:withObject:— that way you don’t need to wrap and unwrap your non-object types.But like I said:
Measure your app before performing any optimizations!
Including these measures, I also reduced the number of run loops this code was executed. This measure improved performance of my app drastically.