7
votes

Comment faire une copie exacte d'un uiImage retourné d'un uiImagePickerController?

J'ai des besoins divergents pour l'image renvoyée de la caméra iPhone. Mon application échoue à l'image vers le bas pour le téléchargement et l'affichage et, récemment, j'ai ajouté la possibilité de sauvegarder l'image sur l'application Photos.

Au début, je cédais la valeur renvoyée à deux variables distinctes, mais il s'est avéré qu'ils étaient Partage du même objet, alors j'avais deux images à la mise à l'échelle au lieu d'en avoir une à pleine échelle.

Après avoir compris que vous ne pouvez pas faire uiimage * copiimage = [copie myImage]; , j'ai fait une copie en utilisant imagewithcgimage , par correspondance. Malheureusement, cela ne fonctionne pas parce que la copie (ici culturePedimage ) finit par rotation 90º de l'original. xxx

est un moyen de copier L'image UIImagePickerControlLeriginalImageImage sans la modifier dans le processus?


5 commentaires

Avez-vous fini par réparer cela? Si oui, pouvez-vous modifier la question avec la solution? Merci!


Pardon. Je n'ai pas eu la chance de travailler sur ce code dans un moment. Va certainement mettre à jour cela une fois que je suis de retour dans ce projet ... ce qui devrait être, er, quelque temps cette année.


UiImage est immuable. Donc, il ne devrait pas imaginer si deux pointeurs pointeront sur le même objet ou des mêmes objets.


Ouais. Si ce n'est pas évident des horodatages, je ne suis jamais revenu à ce projet et, autant que je sache, il a été gisement par les propriétaires d'origine, il est donc peu probable que je ne choisisse jamais une réponse gagnante car je ne suis pas dans une position tester les nouvelles réponses.


Juste FYI: J'ai rencontré un problème similaire et j'ai essayé une copie profonde comme suggérée dans Un autre thread et Cela a servi mon besoin. La réponse suggérée ci-dessous n'a pas fonctionné pour moi, car les deux copies étaient toujours modifiées comme si elles partagent les mêmes données (j'ai utilisé GlkTexTreLoader et parfois ils ont modifié les données dans UIImage avec des options telles que l'origine de gauche).


5 Réponses :


2
votes
UIImage *newImage = [UIImage imageWithData:UIImagePNGRepresentation(oldImage)];

2 commentaires

Un test rapide a montré le même problème lors de l'utilisation de l'imageWithData: au lieu d'imageWithCGIMAGE :. :(


Il s'agit en fait d'une méthode de travail qui copie les données sous-jacentes et génère une nouvelle uIimage avec un nouveau support CGIMAGE. Si l'image est pivotée, c'est parce que les données sous-jacentes sont en rotation et que l'uIimage nécessite une valeur d'orientation à régler pour corriger la rotation.



17
votes

Cela semble fonctionner, mais vous pourriez faire face à des problèmes de mémoire en fonction de ce que vous faites avec Newimage:

CGImageRef newCgIm = CGImageCreateCopy(oldImage.CGImage);
UIImage *newImage = [UIImage imageWithCGImage:newCgIm scale:oldImage.scale orientation:oldImage.imageOrientation];


1 commentaires

Je pense que vous devez également ajouter cgimagerelase (newcgim); après cela. Je l'ai utilisé sans cgimagerelase dans l'application de dessin et a causé des avertissements de mémoire et des accidents.



8
votes

Cela devrait fonctionner:

UIImage *newImage = [UIImage imageWithCGImage:oldImage.CGImage];


1 commentaires

Cela perdra de qualité si olimimage.cale> 1 . Utilisation de ImageWithCGIMage: Échelle: Orientation: est préférable.



0
votes

Je pense que vous devez créer un contexte d'image (CGContextref). Dessinez l'uiimage.cgimage dans le contexte avec la méthode CGContextDrawimage (...), puis obtenez l'image du contexte avec cgbitmapContextCreateImage (...). Avec une telle routine, je suis sûr que vous pouvez obtenir la copie réelle de l'image souhaitée. J'espère que cela vous a aidé.


0 commentaires

5
votes

Copier les données du support et le pivoter

Cette question pose une question commune sur uiimage code> d'une manière légèrement différente. Essentiellement, vous avez deux problèmes connexes - copie et rotation profonde. Un uiimage code> est juste un conteneur et possède une propriété d'orientation utilisée pour l'affichage. Un uiimage code> peut contenir ses données de support sous forme de cgimage code> ou CIIMAGE code>, mais le plus souvent en tant que cgimage code>. Le cgimage code> est une structure d'informations qui inclut un pointeur aux données sous-jacentes et si vous lisez les documents, la copie de la structure ne copie pas les données. SO ... P>

Copie profonde h3>

Comme je vais arriver au paragraphe suivant, la copie en profondeur des données laissera l'image pivotée car l'image est tournée dans les données sous-jacentes.

UIGraphicsBeginImageContext(zebra!.size)
zebra!.drawInRect(CGRectMake(0, 0, zebra!.size.width, zebra!.size.height))
let copy = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()


2 commentaires

Merci, Cameron. Comme mentionné ci-dessus, je ne peux pas vraiment confirmer que cela résout le problème que je possétit il y a 5 ans, mais que, comme vous avez pris le temps d'enseigner plutôt que de simplement démontrer, c'est à vous!


J'ai rencontré les deux informations séparément au fil du temps. Il n'est pas immédiatement évident pour les utilisateurs d'UIMAGE qu'il s'agit simplement d'une enveloppe ou que les données sous-jacentes pourraient être à l'envers et à l'envers. Je suppose que cela a du sens quand quelqu'un le dit, mais tel est la magie.