0

I have the code by which I can take a picture from the camera or from the gallery of the phone, But I want to save the image in the core data that I find it difficult. I read a lot about it and I'm not sure with the image as string or binary data And how to save it and how to get it.

@property (strong) NSMutableArray *allPic;
@property (strong) NSManagedObject *Image;
@end
@implementation ViewController



-(NSManagedObjectContext *)managedObjectContext
{
    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
    if ([delegate performSelector:@selector(managedObjectContext)]) {
        context = [delegate managedObjectContext];
    }
    return context;
}
-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Fetch the devices from persistent data store
    NSManagedObjectContext *managedObjectContext = [self     managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Picture"];
    self.allPic = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
}


-(void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)takePic:(id)sender {

    // ALERT SHEET.
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];

    //CAMERA
    UIAlertAction *openCamrea = [UIAlertAction actionWithTitle:@"צלם" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
    {
        // If device has no camera.
        if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
        {
            UIAlertController *alertNoCamera = [UIAlertController alertControllerWithTitle:@"Error" message:@"Device has no camera" preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){}];
            [alertNoCamera addAction:ok];
            [self presentViewController:alertNoCamera animated:YES completion:nil];
        }
        else// if  have a camera.
        {
           UIImagePickerController *picker = [[UIImagePickerController alloc] init];
           picker.delegate = self;
           picker.allowsEditing = YES;
           picker.sourceType = UIImagePickerControllerSourceTypeCamera;


           [self presentViewController:picker animated:YES completion:NULL];
        }
    }];
    // GALLERY
    UIAlertAction *openGallery = [UIAlertAction actionWithTitle:@"גלריה" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
    {
        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.delegate = self;
        picker.allowsEditing = YES;
        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

        [self presentViewController:picker animated:YES completion:NULL];
    }];

    [alert addAction:openCamrea];
    [alert addAction:openGallery];
    [self presentViewController:alert animated:YES completion:nil];
}

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
     //save image

{
mimpami
  • 83
  • 1
  • 10
  • What you need to do is store url of image in your core data and if you are capturing image and not storing it in your gallery then store image in your DocumentDirectory and store it's path in url format in core data. As storing image in core data is not a feasible solution, as it will increase the size of db so you just need to store path of image. In case if you are picking image from gallery then you just need to store it's path and not the image in DocumentDirectory as it is already present in your gallery. – Dhaivat Vyas Nov 21 '15 at 09:40
  • You used earlier in DocumentDirectory but when I deleted the picture from the album, is not deleted from the app and it became complicated for me .. – mimpami Nov 21 '15 at 10:34
  • In addition, I could not use an array of images in DocumentDirectory – mimpami Nov 21 '15 at 10:35
  • Yes you can use array of images in DocumentDirectory and store images in specific folder with unique name, and get all images in array format by getting all files from the specific folder in DocumentDirectory. The same image name can be stored in core data, and if you required you can store images in DocumentDirectory so if you want to delete image from gallery you can and it will not affect you application. – Dhaivat Vyas Nov 21 '15 at 15:31

2 Answers2

0

I think right way will be saving file in directory and storing path to CoreData. Here is how I have achieved it:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [self dismissViewControllerAnimated:YES completion:nil];
    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        [self.view makeToast:@"Saving Captured Image!" duration:2.0f position:@"top"];
        UIImage *image = info[UIImagePickerControllerOriginalImage];
        [self performSelectorInBackground:@selector(saveImage:) withObject:image];
    }
}

- (void) saveImage : (UIImage *) image  {
    // image detail
    //    NSData *data = UIImagePNGRepresentation(image);
    NSData *data = UIImageJPEGRepresentation(image, 1.0f);
    NSString *imagePath = [self pathForMedia:MediaTypeImage name:[self getImageName:data]];

    //WRITE FILE
    BOOL saved = [data writeToFile:imagePath atomically:YES];
    if (!saved)
        return;

    //Now save: `imagePath` to core Data.
}

- (NSString *) getImageName : (NSData *) imageData {
    return [NSString stringWithFormat:@"%@.%@",[self getUniqueId], [self contentTypeForImageData:imageData]];
}

- (NSString *) pathForMedia : (MediaType) type name : (NSString *) name{
    NSString *foldername = [NSString stringWithFormat:@"/%@/%@", ((type == MediaTypeImage) ? @"Photos" : @"Videos"), name];
    return [[self getUserDocumentDir] stringByAppendingPathComponent:foldername];
}


- (NSString *)contentTypeForImageData:(NSData *)data {
    uint8_t c;
    [data getBytes:&c length:1];

    switch (c) {
        case 0xFF:
            return @"jpg";
        case 0x89:
            return @"png";
        case 0x47:
            return @"gif";
        case 0x49:
            break;
        case 0x42:
            return @"bmp";
        case 0x4D:
            return @"tiff";
    }
    return nil;
}


- (NSString *) getUniqueId {
    CFUUIDRef unqiueId = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, unqiueId);
    CFRelease(unqiueId);    
    return [(__bridge NSString*)string stringByReplacingOccurrencesOfString:@"-"withString:@""];
}
rptwsthi
  • 10,094
  • 10
  • 68
  • 109
0

To Save Image in Core Data:

You can store images in Core Data using the Binary Data attribute type. However you should be aware of a few things:

Always convert your UIImage to a portable data format like png or jpg For example:

NSData *imageData = UIImagePNGRepresentation(image);

Enable "Allows external storage" on this attribute

enter image description here

Core Data will move the data to an external file if it hits a certain threshold. This file is also completely managed by Core Data, so you don't have to worry about it.

If you run into performance issues, try moving the Binary Data attribute to a separate entity.

You should abstract the conversion to NSData behind the interface of your NSManagedObject subclass, so you don't have to worry about conversions from UIImage to NSData or vice versa.

If your images are not strongly related to the entities in your model, I would suggest storing them outside of Core Data.

To Take Images from gallery or camera:

{

    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {

        UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                              message:@"Device has no camera"
                                                             delegate:nil
                                                    cancelButtonTitle:@"OK"
                                                    otherButtonTitles: nil];

        [myAlertView show];
        return;

    }
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = YES;
    picker.sourceType = UIImagePickerControllerSourceTypeCamera;

    //if you want to take image from gallery

    //picker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
    //picker.sourceType=UIImagePickerControllerSourceTypeSavedPhotosAlbum;

    [self presentViewController:picker animated:YES completion:nil];
}

Hope this helps.

Ronak Chaniyara
  • 5,335
  • 3
  • 24
  • 51
  • I think I managed to save the image, in the core data, but how I could get it back, I will post another question, thank you! – mimpami Nov 21 '15 at 10:55
  • If answer helped, please mark it as accepted answer and to retrieve images back you can refer http://stackoverflow.com/questions/3353172/save-and-retrieve-of-an-uiimage-on-coredata – Ronak Chaniyara Nov 21 '15 at 11:11
  • Sorry it did not help me I've seen this answer here: Http://stackoverflow.com/questions/16685812/how-to-store-an-image-in-core-data – mimpami Nov 21 '15 at 11:14