4

次のコードを使用して、アプリケーションのユーザーが写真を撮影/選択できるようにしています。写真はドキュメント ディレクトリに保存され、UIImageView の画像として設定されます。

    -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {

        if (actionSheet.tag == 0){
            if (buttonIndex == 0) {
                NSLog(@"Take Picture Button Clicked");
                // Create image picker controller
                UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

                // Set source to the camera
                imagePicker.sourceType =  UIImagePickerControllerSourceTypeCamera;

                // Delegate is self
                imagePicker.delegate = self;

                // Show image picker
                [self presentModalViewController:imagePicker animated:YES];
            } 
            else if (buttonIndex == 1) {
                NSLog(@"Choose From Library Button Clicked");
                // Create image picker controller
                UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

                // Set source to the camera
                imagePicker.sourceType =  UIImagePickerControllerSourceTypePhotoLibrary;

                // Delegate is self
                imagePicker.delegate = self;

                // Show image picker
                [self presentModalViewController:imagePicker animated:YES];
            } 
            else if (buttonIndex == 2) {
                NSLog(@"Cancel Button Clicked");
            } 
        }
......

- (void)saveImage:(UIImage*)image:(NSString*)imageName 
{ 
    NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.

    NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it

    NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory

    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageName]]; //add our image to the path 

    [fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)

    receiptImageView1.image = [UIImage imageWithContentsOfFile:fullPath];
    self.receiptImage1 = fullPath;

    NSLog(@"image saved");
}

//Receive the image the user picks from the image picker controller
-(void)imagePickerController:(UIImagePickerController*)picker
didFinishPickingMediaWithInfo:(NSDictionary*)info {
    UIImage* image = [info objectForKey: UIImagePickerControllerOriginalImage];
    NSString* imageName = @"Receipt1Image1";
    [self saveImage:image :imageName];
}

基本的に私の問題は、このコードの実行が非常に遅いように見えることです。たとえば、カメラロールから画像を選択すると、最終的に保存されて呼び出しビューに戻りますが、長い遅延の後でのみ..

誰でもこれに光を当てることができますか?

4

2 に答える 2

2

同様の質問に回答しました。わかりやすくするために、ここにコピーします。

画像の解像度によってはUIImagePNGRepresentation、ファイル システムへの書き込みと同様に、実際には非常に遅くなる可能性があります。

これらのタイプの操作は常に非同期キューで実行する必要があります。テスト時にアプリケーションのパフォーマンスが十分に高いと思われる場合でも、非同期キューを使用する必要があります。アプリケーションがユーザーの手に渡ると、デバイスが実行している他のプロセスによって保存が遅くなる可能性があるかどうかはわかりません。 .

iOS の新しいバージョンでは、Grand Central Dispatch (GCD) を使用して非同期保存を非常に簡単に行うことができます。手順は次のとおりです。

  1. NSBlockOperation画像を保存する を作成します
  2. ブロック操作の完了ブロックで、ディスクからイメージを読み取り、表示します。ここでの唯一の注意点は、メイン キューを使用して画像を表示する必要があることです。すべての UI 操作はメイン スレッドで実行する必要があります
  3. ブロック操作を操作キューに追加して、その進行を観察してください!

それでおしまい。コードは次のとおりです。

// Create a block operation with our saves
NSBlockOperation* saveOp = [NSBlockOperation blockOperationWithBlock: ^{

   [UIImagePNGRepresentation(image) writeToFile:file atomically:YES];
   [UIImagePNGRepresentation(thumbImage) writeToFile:thumbfile atomically:YES];

}];

// Use the completion block to update our UI from the main queue
[saveOp setCompletionBlock:^{

   [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 

      UIImage *image = [UIImage imageWithContentsOfFile:thumbfile];
      // TODO: Assign image to imageview

   }];
}];

// Kick off the operation, sit back, and relax. Go answer some stackoverflow
// questions or something.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:saveOp];

このコード パターンに慣れると、何度も使用するようになります。これは、大規模なデータセットを生成する場合や、ロード時に長時間の操作を行う場合などに非常に役立ちます。基本的に、UI の遅延を最小限に抑える操作は、このコードに適しています。メイン キューにいない間は、UI に対して何もできず、他のすべてがケーキであることを覚えておいてください。

于 2012-11-07T23:03:00.933 に答える