CGContextDrawImage est EXTRÊMEMENT lente après la grande UIImage entraînée

Il semble que CGContextDrawImage(CGContextRef, CGRect, CGImageRef) effectue BIEN PIRE lors de l'élaboration d'un CGImage qui a été créé par CoreGraphics (c'est à dire avec CGBitmapContextCreateImage) que lors de l'élaboration de la CGImage qui soutient une UIImage. Voir cette méthode d'analyse:

-(void)showStrangePerformanceOfCGContextDrawImage
{
    ///Setup : Load an image and start a context:
    UIImage *theImage = [UIImage imageNamed:@"reallyBigImage.png"];
    UIGraphicsBeginImageContext(theImage.size);
    CGContextRef ctxt = UIGraphicsGetCurrentContext();    
    CGRect imgRec = CGRectMake(0, 0, theImage.size.width, theImage.size.height);


    ///Why is this SO MUCH faster...
    NSDate * startingTimeForUIImageDrawing = [NSDate date];
    CGContextDrawImage(ctxt, imgRec, theImage.CGImage);  //Draw existing image into context Using the UIImage backing    
    NSLog(@"Time was %f", [[NSDate date] timeIntervalSinceDate:startingTimeForUIImageDrawing]);

    ///Create a new image from the context to use this time in CGContextDrawImage:
    CGImageRef theImageConverted = CGBitmapContextCreateImage(ctxt);

    ///This is WAY slower but why??  Using a pure CGImageRef (ass opposed to one behind a UIImage) seems like it should be faster but AT LEAST it should be the same speed!?
    NSDate * startingTimeForNakedGImageDrawing = [NSDate date];
    CGContextDrawImage(ctxt, imgRec, theImageConverted);
    NSLog(@"Time was %f", [[NSDate date] timeIntervalSinceDate:startingTimeForNakedGImageDrawing]);


}

Donc je suppose que la question est, #1 ce qui peut être à l'origine de ce et n ° 2 est-il un moyen de contourner cela, c'est à dire d'autres façons de créer un CGImageRef qui peut être plus rapide? Je me rends compte que je pouvais tout convertir UIImages premier mais c'est un vilain solution. J'ai déjà le CGContextRef assis là.

Mise à JOUR : Ce qui semble ne pas nécessairement être vrai lors de l'élaboration de petites images? Qui peut être un indice - que ce problème est amplifié lorsque des images de grande taille (c'est à dire pleine taille de la caméra photos) sont utilisés. 640 x 480 semble être assez similaire en termes de temps d'exécution avec la méthode

Mise à JOUR 2 : Ok, j'ai découvert quelque chose de nouveau.. Sa fait PAS le soutien de la CGImage qui est de modifier la performance. Je peux flip-flop de l'ordre de 2 étapes et de faire de la UIImage méthode se comporter lentement, tandis que le "nu" CGImage sera super rapide. Il semble selon ce que vous effectuez deuxième à souffrir de terribles performance. Cela semble être le cas, à MOINS de me libérer de la mémoire en appelant CGImageRelease sur l'image que j'ai créé avec CGBitmapContextCreateImage. Puis le UIImage soutenu méthode sera rapide par la suite. À l'inverse, il n'est pas vrai. Ce qui donne? "Bondé" la mémoire ne devrait pas affecter les performances de ce genre, devrait-il?

Mise à JOUR 3 : parle trop vite. La mise à jour précédente est vraie pour les images à la taille de 2048x2048 pixels, mais le renforcement de la 1936x2592 (pour l'appareil), le nu CGImage méthode est plus lente, quel que soit l'ordre d'exploitation ou la situation de mémoire. Peut-être il y a quelques CG limites internes qui font un 16MB image efficace alors que la 21MB image ne peut pas être gérées efficacement. Ses littéralement 20 fois plus lent à tirer la caméra que 2048x2048. En quelque sorte UIImage offre à ses CGImage de données beaucoup plus rapide qu'un pur CGImage objet n'. o.O

Mise à JOUR 4 : j'ai pensé que cela pourrait avoir à faire avec un peu de mise en mémoire cache chose, mais le résultat est le même, que la UIImage est chargé avec la non-mise en cache [UIImage imageWithContentsOfFile] comme si [UIImage imageNamed] est utilisé.

Mise à JOUR 5 (Jour 2) : Après la création de manière plus de questions que de a répondu, hier, je l'ai quelque chose solide aujourd'hui. Ce que je peux dire pour sûr, c'est la suivante:

  • La CGImages derrière une UIImage ne pas utiliser de l'alpha. (kCGImageAlphaNoneSkipLast). J'ai pensé que peut-être qu'ils ont été les plus rapides à être établi en raison de mon contexte à l'aide de l'alpha. J'ai donc modifié le contexte de l'utilisation kCGImageAlphaNoneSkipLast. Cela rend le dessin BEAUCOUP plus rapide, à MOINS que:
  • Dessin dans un CGContextRef avec une UIImage PREMIER, fait TOUS les de dessin d'image lente

J'ai prouvé par 1)d'abord, la création d'un non-alpha contexte (1936x2592). 2) il a Rempli de façon aléatoire de couleur 2x2 places. 3) Full frame dessin un CGImage dans ce contexte a été RAPIDE (.17 secondes) 4) a Répété l'expérience, mais rempli de contexte avec une CGImage à l'appui d'une UIImage. Ultérieure image complète de dessin a+ de 6 secondes. SLOWWWWW.

En quelque sorte de dessin dans un contexte avec un (Grand) UIImage ralentit considérablement tous les dessin dans ce contexte.

  • Sur quel appareil avez-vous tester? 2k x 2k pixels des images des besoins ~16 mo de mémoire, alors que sur l'iPhone 3G il y a seulement 30 mo de mémoire libre pour l'application.
  • Tout cela est fait sur un iPhone 4 dans un bac à sable application de test... je suis certain de ne pas obtenir des avertissements de mémoire.
InformationsquelleAutor typewriter | 2011-09-26