2010-03-29 9 views
1

Je travaille avec des images de taille 2 à 4MB. Je travaille avec des images de résolution 1200x1600 en effectuant des opérations de mise à l'échelle, de translation et de rotation. Je veux ajouter une autre image à ce sujet et l'enregistrer dans un album photo. Mon application plante après avoir correctement modifié une image et enregistré des photos. Ca se passe à cause de la taille des images je pense. Je veux maintenir les 90% de résolution des images. Je libère quelques images quand je reçois un avertissement de la mémoire. Mais encore il se bloque comme je travaille avec 2 images de taille 3Mo chacune et le contexte de taille 1200x1600 et obtenir une image du contexte en même temps.Comment travailler avec des images (png's) de taille 2-4Mb

Y at-il un moyen de compresser des images et de travailler avec?

+0

Juste une note rapide, que vous pouvez ou ne savez pas déjà, mais sera utile pour ceux qui ne savent pas: la taille de l'image en mémoire est généralement calculée comme w * h * 4, donc dans ce cas, 1200 * 1600 * 4 = 7 680 000 (plus de 7 Mo). – Jasarien

+0

Vous devez confirmer si ce sont des problèmes de mémoire et la taille de l'image qui est le problème, dans votre question, vous ne semblez pas sûr. Par exemple, si vous utilisez des images de 500x500 cela arrive-t-il encore? –

Répondre

3

J'en doute. Même la compression et la décompression d'une image sans rien y faire perdent de l'information. Je suspecte que tous les algorithmes pour manipuler des images compressées seraient désespérément lossy. Cela dit, cela peut être techniquement possible. Par exemple, la rotation d'une transformée de Fourier fait également tourner l'image originale. Mais la compression d'image pratique n'est généralement pas aussi simple que de simplement calculer une transformée de Fourier. Alternativement, vous pouvez écrire des algorithmes fragmentaires qui hacher l'image en morceaux de petite taille, transformer les pièces et les réassembler après. Vous pouvez également fournir une vue en temps réel du processus en appliquant la même transformation à une version plus petite de l'image complète.

+0

Pourquoi downvote une réponse parfaitement bonne? Au moins avoir la décence de laisser un commentaire – pheelicks

1

La clé sera de ne jamais décoder complètement l'image entière en mémoire à pleine taille.

  1. Si vous avez besoin pour afficher l'image, il n'y a aucune raison de le faire en taille réelle - l'affichage sur l'iPhone est trop petit pour tirer profit de cela. Pour les objets image à afficher, décodez l'image sous forme réduite.

  2. Pour le traitement, vous devrez écrire du code personnalisé qui fonctionne sur un flux de pixels plutôt que sur un tableau en mémoire. Je ne sais pas si cela est déjà disponible sur l'iPhone, mais vous pouvez l'écrire vous-même en écrivant directement à l'API libpng library.

Par exemple, votre code en ce moment ressemble probablement quelque chose comme ça (code pseudo)

img = ReadImageFromFile("image.png") 
img2 = RotateImage(img, 90) 
SaveImage(img2, "image2.png") 

L'essentiel à comprendre, est que dans ce cas, img ne sont pas les données du PNG fichier (2 Mo), mais l'image entièrement non compressé (~ 6 Mo). RotateImage (ou quel que soit son nom) renvoie une autre image à peu près de cette taille. Si vous agrandissez, c'est encore pire.

Vous voulez un code qui ressemble plus à ceci (mais il n'y aurait pas des API pour vous de le faire - vous pourriez avoir à écrire vous-même)

imgPixelGetter = PixelDecoderFromFile("image.png") 
imgPixelSaver = OpenImageForAppending("image2.png") 
w = imgPixelGetter.Width 
h = imgPixelGetter.Height 

// set up a 90 degree rotate 
imgPixelSaver.Width = h 
imgPixelSaver.Height = w 

// read each vertical scanline of pixels 
for (x = 0; x < w; ++x) { 
    pixelRect = imgPixelGetter.ReadRect(x, 0, 1, h) // x, y, w, h 
    pixelRect.Rotate(90); // it's now got a width of h and a height of 1 
    imgPixelSaver.AppendScanLine(pixelRect) 
} 

Dans cet algorithme, on n'a jamais eu la l'image entière dans la mémoire à la fois - vous l'avez lue morceau par morceau et l'a sauvée. Vous pouvez écrire des algorithmes similaires pour la mise à l'échelle et le recadrage. Le compromis est qu'il sera plus lent que de simplement le décoder en mémoire - cela dépend du format de l'image et du code qui fait ReadRect(). Malheureusement, le format PNG n'est pas conçu pour ce type d'accès aux pixels.