2010-11-23 40 views
0

J'ai une application pour iPhone qui, entre autres, permet aux utilisateurs de stocker des photos. Lorsqu'une nouvelle photo est ajoutée au magasin de données de l'application, je mets en cache une version miniature de l'image afin que les grilles de miniatures de photos se chargent dans un délai raisonnable.Mise à jour des images sauvegardées pour l'écran Retina

Le problème est que ces vignettes sont superbes sur un écran d'affichage Pre-Retina, mais elles ont l'air un peu flou sur les affichages RD. Ce n'est pas si grave que les images sont inutilisables, mais j'aimerais vraiment pouvoir profiter pleinement de Retina Display pour les utilisateurs d'images enregistrés avec les anciennes versions de mon application.

Le problème est que la recréation de toutes ces vignettes prend trop de temps. Dans mes tests, il a fallu environ une minute et demie pour ré-encoder un exemple de base de données en miniatures haute résolution (certes une grande) sur mon iPhone 4. Ce sera encore pire sur du matériel plus ancien.

Comment puis-je contourner le problème? Faire une migration ponctuelle semble hors de question, étant donné les résultats de performance ci-dessus. D'autres options réduisent paresseusement les vignettes (c'est-à-dire lorsqu'elles sont affichées à l'écran), puis les enregistrent dans la base de données à ce moment-là. Les écrans remplis d'anciennes images seront lents la première fois qu'ils seront visionnés, puis plus rapides après cela.

Y a-t-il d'autres approches à considérer? Quelqu'un d'autre a fait face à ce problème?

Répondre

-1

Les écrans remplis d'anciennes images seront lents la première fois qu'ils seront affichés, puis plus rapides après cela.

Il ne doit pas être lent.

C'est un bit d'une douleur, mais vous pouvez faire la plupart de votre traitement dans un fil de fond. Définissez la priorité du thread sur quelque chose de faible (comme 0,1) pour éviter de rendre l'interface utilisateur trop lente. La méthode la plus simple consiste à configurer un NSOperation pour chaque image que vous devez convertir et à les ajouter à un NSOperationQueue avec maxConcurrentOperationCount = 1.

Si les écritures ne sont pas atomiques, dans -applicationDidEnterBackground: ou -applicationWillTerminate: (ou dans quelque chose écoutant les notifications de notifications correspondantes), faites quelque chose comme [queue cancelAllOperations]; for (NSOperation * operation in queue) { [operation setThreadPriority:1]; } [queue waitUntilAllOperationsAreFinished];; vous obtenez environ 10 secondes, ce qui devrait suffire pour que la conversion de l'image finisse d'écrire sur le disque (et ainsi éviter les fichiers à moitié écrits). Pour plus de protection, vérifiez [operation isCancelled] immédiatement avant l'écriture si cela peut prendre plus de 10 secondes. Évidemment, dans -applicationWillEnterForeground :, vous devriez recommencer la conversion (en se rappelant que certaines images ont déjà été converties).

problèmes de concurrence sont amusants pour traquer ...

(Notez que [data writeToFile:path atomically:YES] ne suffit pas — il est susceptible de laisser des fichiers temporaires qui traînent si l'application est tué au cours de l'écriture. Je vous recommande de stocker les vignettes dans Core Data si vous le pouvez, mais cela pourrait être hors de question pour les applications existantes.)

0
  1. Je n'aime pas l'idée que vous essayez de convertir les images.
  2. L'utilisateur s'impatientera rapidement et dira que votre application est boguée et prend du temps à charger.
  3. Je pense que vous résolvez la situation sans aucun retraitement des images en taille réelle.
  4. Sur un matériel plus ancien, vous n'avez pas d'affichage rétine (donc pas besoin de migrer les images). Si ils ont un écran rétine, ils ont un iPod iPhone rapide.

Je vous suggère de résoudre graphiquement le problème en affichant les images miniatures. Ainsi, au lieu de plein écran, mettez une bordure autour de cette image et montrez-la à sa vraie résolution (ne l'augmentez pas). Ou montre 4 images où vous montrez normalement 1 (puisque l'écran de l'iPhone est 4x la résolution). Au lieu de rééchantillonner l'image massive d'origine, vous pouvez effectuer un suréchantillonnage bicubique de la vignette, ce qui en fait 4 fois la taille. Cela le rendra légèrement flou, mais il devrait être meilleur que la mise à l'échelle de l'iPhone qui aura l'air vraiment mauvais. Le suréchantillon serait ultra rapide car il travaille avec une petite image.

Je ne peux pas vous aider sur le suréchantillonnage mais il y aura du code quelque part.

Cheers, John.

+1

-1. Les images sont traitées comme des textures sur le GPU, et (pour autant que je sache) utilisent l'interpolation bicubique par défaut. –

+0

DUDE! Vous me marquez et vous n'avez pas raison. Les images d'affichage non retina ne sont PAS affichées en utilisant l'interpolation bicubique. Les pixels sont doublés. 1 pixel devient 4 pixels de la même couleur et semble pixélisé et dentelé. Bicubic ne double pas le pixel et vous donne une image beaucoup plus lisse. Veuillez corriger votre vote s'il vous plaît. –