¿Qué tengo que hacer para guardar una imagen de mi programa ha generado (posiblemente de la cámara, posiblemente no) para el sistema de biblioteca de fotos en el iPhone?

InformationsquelleAutor jblocksom | 2008-10-07

14 Comentarios

  1. 409

    Puede utilizar esta función:

    UIImageWriteToSavedPhotosAlbum(UIImage *image, 
                                   id completionTarget, 
                                   SEL completionSelector, 
                                   void *contextInfo);

    Sólo necesita completionTarget, completionSelector y contextInfo si usted desea ser notificado cuando el UIImage es terminar de guardar, de lo contrario puede pasar en nil.

    Ver el la documentación oficial para UIImageWriteToSavedPhotosAlbum().

    • Hace este trabajo en el simulador?
    • sí, funciona en el simulador
    • La madre de corto funciones…..
    • Toma +1 para la respuesta correcta
    • Hola gracias por tu gran solución. Aquí tengo una duda, ¿cómo podemos evitar duplicados, mientras que la imagen se guardan en la biblioteca de fotos. Gracias de antemano.
    • Si quieres ahorrar en la mejor calidad, ver esto: stackoverflow.com/questions/1379274/…
    • Recuerde agregar la clave de la Privacidad de la Foto, del Uso de la Biblioteca Descripción’ a tu info.archivo plist
    • Ahora tendrá que añadir la Privacidad – Fotos de la Biblioteca de Adiciones Descripción de Uso’ como de iOS 11 para guardar las fotos de los usuarios álbum.
    • cómo dar un nombre a las imágenes guardadas?

  2. 63

    En desuso en iOS 9.0.

    Hay mucho más rápido, a continuación, UIImageWriteToSavedPhotosAlbum manera de hacerlo con iOS 4.0+ AssetsLibrary marco

        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    
        [library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
        if (error) {
        //TODO: error handling
        } else {
        //TODO: success handling
        }
    }];
    [library release];
    • Es allí una manera de ahorrar arbitraria de metadatos junto con la foto?
    • Traté de guardar usando ALAssetsLibrary, sólo se necesita el mismo tiempo para guardar como UIImageWriteToSavedPhotosAlbum.
    • Y esta se congela la cámara 🙁 supongo que no es de fondo compatibles ?
    • Este es mucho más limpio b/c puede usar un bloque para manejar su finalización.
    • +1 por el respeto a la orientación de imagen
    • Estoy usando este código y estoy incluyendo este marco de #import <AssetsLibrary/AssetsLibrary.h> no la AVFoundation. No debería la respuesta será editada? @Denis
    • Bueno, pero ha sido desaprobado en iOS 9 SDK.

  3. 13

    Una cosa para recordar: Si utiliza una devolución de llamada, asegúrese de que el selector se ajusta de la siguiente forma:

    - (void) image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo;

    De lo contrario, puede bloquearse con un error como el siguiente:

    [NSInvocation setArgument:atIndex:]: index (2) out of bounds [-1, 1]

  4. 10

    Acaba de pasar las imágenes a partir de una matriz a como lo

    -(void) saveMePlease {
    
    //Loop through the array here
    for (int i=0:i<[arrayOfPhotos count]:i++){
             NSString *file = [arrayOfPhotos objectAtIndex:i];
             NSString *path = [get the path of the image like you would in DOCS FOLDER or whatever];
             NSString *imagePath = [path stringByAppendingString:file];
             UIImage *image = [[[UIImage alloc] initWithContentsOfFile:imagePath]autorelease];
    
             //Now it will do this for each photo in the array
             UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
            }
    }

    Lo siento por error tipográfico un poco solo hice sobre la marcha, pero usted consigue el punto

    • El uso de este se pierda algunas de las fotos, lo he intentado. La manera correcta de hacerlo es utilizar la llamada de nuevo a partir de la finalización del selector.
    • podemos guardar las imágenes con el nombre personalizado?
    • Nunca se debe utilizar para el bucle para esto. Esto conduce a la condición de carrera y se bloquea.
  5. 4

    Al guardar un conjunto de fotos, no se puede utilizar un bucle for, haga lo siguiente

    -(void)saveToAlbum{
       [self performSelectorInBackground:@selector(startSavingToAlbum) withObject:nil];
    }
    -(void)startSavingToAlbum{
       currentSavingIndex = 0;
       UIImage* img = arrayOfPhoto[currentSavingIndex];//get your image
       UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }
    - (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo{ //can also handle error message as well
       currentSavingIndex ++;
       if (currentSavingIndex >= arrayOfPhoto.count) {
           return; //notify the user it's done.
       }
       else
       {
           UIImage* img = arrayOfPhoto[currentSavingIndex];
           UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
       }
    }
  6. 4

    En Swift:

        //Save it to the camera roll /saved photo album
        //UIImageWriteToSavedPhotosAlbum(self.myUIImageView.image, nil, nil, nil) or 
        UIImageWriteToSavedPhotosAlbum(self.myUIImageView.image, self, "image:didFinishSavingWithError:contextInfo:", nil)
    
        func image(image: UIImage!, didFinishSavingWithError error: NSError!, contextInfo: AnyObject!) {
                if (error != nil) {
                    //Something wrong happened.
                } else {
                    //Everything is alright.
                }
        }
    • sí…bueno..pero después de guardar la imagen que desea cargar imagen desde la galería de… cómo hacer que
  7. 4

    Debajo de la función de trabajo. Puede copiar de aquí y pegar allí…

    -(void)savePhotoToAlbum:(UIImage*)imageToSave {
    
        CGImageRef imageRef = imageToSave.CGImage;
        NSDictionary *metadata = [NSDictionary new]; //you can add
        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    
        [library writeImageToSavedPhotosAlbum:imageRef metadata:metadata completionBlock:^(NSURL *assetURL,NSError *error){
            if(error) {
                NSLog(@"Image save eror");
            }
        }];
    }
  8. 2
    homeDirectoryPath = NSHomeDirectory();
    unexpandedPath = [homeDirectoryPath stringByAppendingString:@"/Pictures/"];
    
    folderPath = [NSString pathWithComponents:[NSArray arrayWithObjects:[NSString stringWithString:[unexpandedPath stringByExpandingTildeInPath]], nil]];
    
    unexpandedImagePath = [folderPath stringByAppendingString:@"/image.png"];
    
    imagePath = [NSString pathWithComponents:[NSArray arrayWithObjects:[NSString stringWithString:[unexpandedImagePath stringByExpandingTildeInPath]], nil]];
    
    if (![[NSFileManager defaultManager] fileExistsAtPath:folderPath isDirectory:NULL]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:folderPath attributes:nil];
    }
  9. 1

    mi última respuesta hacerlo..

    para cada imagen que desee guardar, agregar a un NSMutableArray

        //in the .h file put:
    
    NSMutableArray *myPhotoArray;
    
    
    ///then in the .m
    
    - (void) viewDidLoad {
    
     myPhotoArray = [[NSMutableArray alloc]init];
    
    
    
    }
    
    //However Your getting images
    
    - (void) someOtherMethod { 
    
     UIImage *someImage = [your prefered method of using this];
    [myPhotoArray addObject:someImage];
    
    }
    
    -(void) saveMePlease {
    
    //Loop through the array here
    for (int i=0:i<[myPhotoArray count]:i++){
             NSString *file = [myPhotoArray objectAtIndex:i];
             NSString *path = [get the path of the image like you would in DOCS FOLDER or whatever];
             NSString *imagePath = [path stringByAppendingString:file];
             UIImage *image = [[[UIImage alloc] initWithContentsOfFile:imagePath]autorelease];
    
             //Now it will do this for each photo in the array
             UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
            }
    }
    • He probado la solución, siempre perdido algunas de las fotos. Eche un vistazo a mi respuesta. enlace
  10. 1

    He creado un UIImageView categoría para esto, basado en algunas de las respuestas anteriores.

    Archivo De Encabezado:

    @interface UIImageView (SaveImage) <UIActionSheetDelegate>
    - (void)addHoldToSave;
    @end

    Aplicación

    @implementation UIImageView (SaveImage)
    - (void)addHoldToSave{
        UILongPressGestureRecognizer* longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
        longPress.minimumPressDuration = 1.0f;
        [self addGestureRecognizer:longPress];
    }
    
    -  (void)handleLongPress:(UILongPressGestureRecognizer*)sender {
        if (sender.state == UIGestureRecognizerStateEnded) {
    
            UIActionSheet* _attachmentMenuSheet = [[UIActionSheet alloc] initWithTitle:nil
                                                                              delegate:self
                                                                     cancelButtonTitle:@"Cancel"
                                                                destructiveButtonTitle:nil
                                                                     otherButtonTitles:@"Save Image", nil];
            [_attachmentMenuSheet showInView:[[UIView alloc] initWithFrame:self.frame]];
        }
        else if (sender.state == UIGestureRecognizerStateBegan){
            //Do nothing
        }
    }
    -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
        if  (buttonIndex == 0) {
            UIImageWriteToSavedPhotosAlbum(self.image, nil,nil, nil);
        }
    }
    
    
    @end

    Ahora simplemente llamar a esta función en el imageview:

    [self.imageView addHoldToSave];

    Opcionalmente se puede alterar el minimumPressDuration parámetro.

  11. 1

    En Swift 2.2

    UIImageWriteToSavedPhotosAlbum(image: UIImage, _ completionTarget: AnyObject?, _ completionSelector: Selector, _ contextInfo: UnsafeMutablePointer<Void>)

    Si usted no desea ser notificado cuando la imagen se hace de ahorro, a continuación, usted puede pasar nula en el completionTarget, completionSelector y contextInfo parámetros.

    Ejemplo:

    UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.imageSaved(_:didFinishSavingWithError:contextInfo:)), nil)
    
    func imageSaved(image: UIImage!, didFinishSavingWithError error: NSError?, contextInfo: AnyObject?) {
            if (error != nil) {
                //Something wrong happened.
            } else {
                //Everything is alright.
            }
        }

    Lo importante a destacar aquí es que el método que se observa la imagen de ahorro deben tener estos 3 parámetros de lo contrario va a ejecutar en NSInvocation errores.

    Espero que ayude.

  12. 0

    Puede utilizar este

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       UIImageWriteToSavedPhotosAlbum(img.image, nil, nil, nil);
    });
  13. 0

    Swift 4

    func writeImage(image: UIImage) {
        UIImageWriteToSavedPhotosAlbum(image, self, #selector(finishWriteImage), nil)
    }
    
    @objc private func finishWriteImage(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
    }

Dejar respuesta

Please enter your comment!
Please enter your name here