Оптимизация производительности Quartz2D для сенсорных событий - PullRequest
3 голосов
/ 27 декабря 2011

То, что я делаю, происходит при каждом касании, когда я создаю изображение из неподписанного символа *. Вот моя функция

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

Эта функция вызывается следующим образом:

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

Я использую следующую функцию обратного вызова для освобождения данных.

void freeRawData(void *info, const void *data, size_t size) {
data = nil;
}

Может ли кто-нибудь помочь мне, как я могу оптимизировать скорость этого. На новом iphone работает нормально, но не на старых.

Я вызываю paint в селекторе выполнения, чтобы я не заполучил выполнение, пока оно завершает создание изображений. Также будет полезна любая помощь в создании изображений непосредственно из необработанных данных, то есть unsigned char *.

1 Ответ

1 голос
/ 12 января 2012

Прежде чем пытаться выполнить какую-либо оптимизацию, измерьте , где вы проводите свое время. Инструменты производительности инструментов помогут вам здесь.

Вдобавок ко всему, я вижу кое-что, чего действительно не должно быть в коде, который вы показали:

  • Во-первых, если вы можете реже обходиться рисованием, то сделайте это.
  • Вероятностью того, что цветовое пространство вашего устройства изменится в течение срока службы вашего приложения, можно пренебречь - кэширование цветового пространства в переменной static может сбить время с этого кода.
  • Вы уже делаете рисование на уровне компьютерной графики - не создавая UIImage s, но используя вместо этого CGContextDrawImage, вы также можете сэкономить довольно много времени.
  • Если вам не нужна поддержка iOS 3, используйте dispatch_async вместо performSelector:withObject: - таким образом вам не нужно оборачивать и разворачивать не-объектные типы.

Но, как я уже сказал:

Измерьте ваше приложение перед выполнением любых оптимизаций!

Включая эти меры, я также уменьшил количество циклов выполнения, которые выполнялся этот код. Эта мера значительно повысила производительность моего приложения.

...