IOS'ta UIView'den Uygulama Belgeleri Klasörüne Bir Görüntü Kaydet


114

Bir kullanıcının bir görüntüyü kaydedilebilene kadar yerleştirmesine ve tutmasına izin veren bir UIImageView var. Sorun şu ki, görünüme yerleştirdiğim görüntünün gerçekte nasıl kaydedilip geri alınacağını çözemiyorum.

UIImageView'daki görüntüyü şu şekilde aldım ve yerleştirdim:

//Get Image 
- (void) getPicture:(id)sender {
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = YES;
    picker.sourceType = (sender == myPic) ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    [self presentModalViewController:picker animated:YES];
    [picker release];
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage (UIImage *)image editingInfo:(NSDictionary *)editingInfo {
    myPic.image = image;
    [picker dismissModalViewControllerAnimated:YES];
}

UIImageView'umda seçilen resmi gayet iyi gösteriyor, ancak onu nasıl kaydedeceğimi bilmiyorum. Görünümün diğer tüm parçalarını (çoğunlukla UITextfield) Core Data'ya kaydediyorum. İnsanların önerdiği birçok kod parçasını aradım ve araştırdım ve denedim, ancak ya kodu doğru girmiyorum ya da bu öneriler, kodumun kurulum biçimiyle çalışmıyor. Muhtemelen eski. Metni UITextFields'a kaydetmek için kullandığım eylemi (bir kaydetme düğmesi) kullanarak UIImageView'daki görüntüyü kaydetmek istiyorum. UITextField bilgilerimi şu şekilde kaydediyorum:

// Handle Save Button
- (void)save {

    // Get Info From UI
    [self.referringObject setValue:self.myInfo.text forKey:@"myInfo"];

Daha önce de söylediğim gibi, bunu çalıştırmak için birkaç yöntem denedim, ancak bunu anlayamıyorum. Hayatımda ilk kez cansız bir nesneye fiziksel zarar vermek istedim, ancak kendimi tutmayı başardım.

Kullanıcının UIImageView'a yerleştirdiği görüntüyü uygulamanın belgeler klasörüne kaydedebilmek ve ardından kullanıcı bu görünümü yığına ittiğinde görüntülenmesi için başka bir UIImageView'a yerleştirebilmek istiyorum. Herhangi bir yardım büyük beğeni topluyor!

Yanıtlar:


341

Her şey yolunda adamım. Kendinize veya başkalarına zarar vermeyin.

Muhtemelen bu görüntüleri Core Data'da saklamak istemezsiniz, çünkü veri kümesi çok büyürse bu performansı etkileyebilir. Görüntüleri dosyalara yazmak daha iyidir.

NSData *pngData = UIImagePNGRepresentation(image);

Bu, çektiğiniz görüntünün PNG verilerini çıkarır. Buradan bir dosyaya yazabilirsiniz:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory 
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"image.png"]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file

Daha sonra okumak aynı şekilde çalışır. Yukarıda yaptığımız gibi yolu inşa edin, sonra:

NSData *pngData = [NSData dataWithContentsOfFile:filePath];
UIImage *image = [UIImage imageWithData:pngData];

Muhtemelen yapmak isteyeceğiniz şey, sizin için yol dizeleri oluşturan bir yöntem yapmaktır, çünkü bu kodun her yere dağılmasını istemezsiniz. Şöyle görünebilir:

- (NSString *)documentsPathForFileName:(NSString *)name
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);  
    NSString *documentsPath = [paths objectAtIndex:0];

    return [documentsPath stringByAppendingPathComponent:name]; 
}

Umarım yardımcı olur.


2
tamamen doğru - sadece Apple Depolama Yönergelerinden bahsetmek istiyorum, bu nedenle görüntülerin doğasına
BAĞLI OLARAK,

Önerinizi ve kodunuzu takip ettim. ancak fotoğraf bölümlerinde görünmüyor. Bu nasıl oldu?
NovusMobile

@DaniloCampos Belgeler Dizini içinde bir klasör nasıl oluşturulur ve sonra dosya bu klasörün içine nasıl kaydedilir?
Pradeep Reddy Kypa

3

Swift 3.0 sürümü

let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
        
let img = UIImage(named: "1.jpg")!// Or use whatever way to get the UIImage object
let imgPath = URL(fileURLWithPath: documentDirectoryPath.appendingPathComponent("1.jpg"))// Change extension if you want to save as PNG

do{
    try UIImageJPEGRepresentation(img, 1.0)?.write(to: imgPath, options: .atomic)//Use UIImagePNGRepresentation if you want to save as PNG
}catch let error{
    print(error.localizedDescription)
}

2

Bu Fangming Ning cevabı Swift 4.2 için bir ile güncellenir, tavsiye ve daha Swifty yöntemle belge dizin yolunu almak için ve daha iyi belgelerle. Yeni yöntem için Fangming Ning'e kredi verildi.

guard let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
    return
}

//Using force unwrapping here because we're sure "1.jpg" exists. Remember, this is just an example.
let img = UIImage(named: "1.jpg")!

// Change extension if you want to save as PNG.
let imgPath = documentDirectoryPath.appendingPathComponent("1.jpg")

do {
    //Use .pngData() if you want to save as PNG.
    //.atomic is just an example here, check out other writing options as well. (see the link under this example)
    //(atomic writes data to a temporary file first and sending that file to its final destination)
    try img.jpegData(compressionQuality: 1)?.write(to: imgPath, options: .atomic)
} catch {
    print(error.localizedDescription)
}

Tüm olası Veri yazma seçeneklerine buradan göz atın.


Bu doğru mu? Burada başka bir soruya yanıt olarak , fileURLWithPathbirlikte absoluteStringyanlış olduğunu buldum .
dumbledad

@dumbledad Bilgi için teşekkürler, cevabımı güncelledim ve Swift 4.2 kodunu da yeniden yazdım.
Tamás Sengel

2
#pragma mark - Save Image To Local Directory

- (void)saveImageToDocumentDirectoryWithImage:(UIImage *)capturedImage {
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"/images"];
    
    //Create a folder inside Document Directory
    if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
        [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder

    NSString *imageName = [NSString stringWithFormat:@"%@/img_%@.png", dataPath, [self getRandomNumber]] ;
    // save the file
    if ([[NSFileManager defaultManager] fileExistsAtPath:imageName]) {
        // delete if exist
        [[NSFileManager defaultManager] removeItemAtPath:imageName error:nil];
    }
    
    NSData *imageDate = [NSData dataWithData:UIImagePNGRepresentation(capturedImage)];
    [imageDate writeToFile: imageName atomically: YES];
}


#pragma mark - Generate Random Number

- (NSString *)getRandomNumber {
    NSTimeInterval time = ([[NSDate date] timeIntervalSince1970]); // returned as a double
    long digits = (long)time; // this is the first 10 digits
    int decimalDigits = (int)(fmod(time, 1) * 1000); // this will get the 3 missing digits
    //long timestamp = (digits * 1000) + decimalDigits;
    NSString *timestampString = [NSString stringWithFormat:@"%ld%d",digits ,decimalDigits];
    return timestampString;
}

1

Uzantılı Swift 4

extension UIImage{

func saveImage(inDir:FileManager.SearchPathDirectory,name:String){
    guard let documentDirectoryPath = FileManager.default.urls(for: inDir, in: .userDomainMask).first else {
        return
    }
    let img = UIImage(named: "\(name).jpg")!

    // Change extension if you want to save as PNG.
    let imgPath = URL(fileURLWithPath: documentDirectoryPath.appendingPathComponent("\(name).jpg").absoluteString)
    do {
        try UIImageJPEGRepresentation(img, 0.5)?.write(to: imgPath, options: .atomic)
    } catch {
        print(error.localizedDescription)
    }
  }
}

Kullanım örneği

 image.saveImage(inDir: .documentDirectory, name: "pic")

0

Swift'de:

let paths: [NSString?] = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .LocalDomainMask, true)
if let path = paths[0]?.stringByAppendingPathComponent(imageName) {
    do {
        try UIImagePNGRepresentation(image)?.writeToFile(path, options: .DataWritingAtomic)
    } catch {
        return
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.