0

ばかげた質問かもしれませんが、私はiPhone初心者なので申し訳ありません。

ビデオのすべてのフレームの画像を生成し、それを UIImageView 内の UIScrollview に表示したいと考えています。

それをしようとすると、メモリの警告が表示され、アプリがクラッシュします。

以下は私のコードです。

- (IBAction)onCameraButtonPressed:(id)sender
{
    // Initialize UIImagePickerController to select a movie from the camera roll.
    UIImagePickerController *videoPicker = [[UIImagePickerController alloc] init];
    videoPicker.delegate = self;
    videoPicker.modalPresentationStyle = UIModalPresentationCurrentContext;
    videoPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    videoPicker.mediaTypes = @[(NSString*)kUTTypeMovie];
    [self presentViewController:videoPicker animated:YES completion:nil];
}

#pragma mark Image Picker Controller Delegate

- (void)imagePickerController:(UIImagePickerController *)picker     didFinishPickingMediaWithInfo:(NSDictionary *)info
{
   [self dismissViewControllerAnimated:YES completion:nil];
    currentVideoURL = info[UIImagePickerControllerReferenceURL];
    //Video URL = assets-library://asset/asset.MOV?id=D0A4A3EE-C5F3-49C8-9E45-ADF775B9FA8C&ext=MOV
    //NSLog(@"Video URL = %@",currentVideoURL);
    //imageIndex = 0;
    for (UIImageView *subView in thumbnailScrollView.subviews)
    {
        [subView removeFromSuperview];
    }
    [self generateThumbnailsFromVideoURL:currentVideoURL];
    //[self generateAVAssetThumbnails:currentVideoURL];
    //[self appleImageGenerator:currentVideoURL];
    }

- (void)generateThumbnailsFromVideoURL:(NSURL *)videoURL
{
    AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:videoURL options:nil];
    //NSLog(@"Video duration %lld seconds",asset.duration.value/asset.duration.timescale);
    int videoDuration = (asset.duration.value/asset.duration.timescale);

    if (cmTimeArray.count>0) {
        [cmTimeArray removeAllObjects];
    }
    for (int i = 0; i<videoDuration; i++)
    {
        int64_t tempInt = i;
        CMTime tempCMTime = CMTimeMake(tempInt,1);
        int32_t interval = 15;
        for (int j = 1; j<16; j++)
        {
            CMTime newCMtime = CMTimeMake(j,interval);
            CMTime addition = CMTimeAdd(tempCMTime, newCMtime);
            [cmTimeArray addObject:[NSValue valueWithCMTime:addition]];
        }
    }
    //NSLog(@"Array of time %@ count = %d",cmTimeArray, cmTimeArray.count);
    /*for(int t=0;t < asset.duration.value;t++) {
        CMTime thumbTime = CMTimeMake(t,asset.duration.timescale);
        NSValue *v=[NSValue valueWithCMTime:thumbTime];
        [cmTimeArray addObject:v];
    }
    NSLog(@"Array of time %@ count = %d",cmTimeArray, cmTimeArray.count);*/
    __block int i = 0;
    //__block UIImage *currentImage = nil;
    AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
        if (result == AVAssetImageGeneratorSucceeded) {
            // currentImage = [UIImage imageWithCGImage:im];
            //[framesArray addObject:[UIImage imageWithCGImage:im]];
            [self performSelectorOnMainThread:@selector(insertImageToScrollView:) withObject:[UIImage imageWithCGImage:im] waitUntilDone:NO];
        }
        else
            NSLog(@"Ouch: %@", error.description);
        i++;
        imageIndex = i;
        if(i == cmTimeArray.count) {
            //[self performSelectorOnMainThread:@selector(insertImageToScrollView:) withObject:framesArray waitUntilDone:YES];
        }
    };

    // Launching the process...
    self.generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    self.generator.appliesPreferredTrackTransform=TRUE;
    self.generator.requestedTimeToleranceBefore = kCMTimeZero;
    self.generator.requestedTimeToleranceAfter = kCMTimeZero;
    self.generator.maximumSize = CGSizeMake(40, 40);
    [self.generator generateCGImagesAsynchronouslyForTimes:cmTimeArray completionHandler:handler];
    }

-(void)insertImageToScrollView:(UIImage *)image
{
    int xPosition = (5*imageIndex)+(WIDTH*imageIndex)+OFFSET;
    UIImageView *currentImageView = [[UIImageView alloc]initWithFrame:CGRectMake(xPosition, 5, WIDTH, WIDTH)];
    currentImageView.tag = imageIndex+10;
    currentImageView.image = image;
    [thumbnailScrollView addSubview:currentImageView];
    [thumbnailScrollView setContentSize:CGSizeMake(xPosition+WIDTH+5,thumbnailScrollView.frame.size.height)];
}
4

2 に答える 2

3

すべての画像をビューにロードしていますが、一度に表示されるのはごくわずかです。画像の量によっては、これは大量のメモリを消費する可能性があります。

次のアプローチを検討できます。

すべての画像を生成してローカル ストレージに書き込み、画像のファイル URL を配列に格納します。

スクロールビューの場合、次の画像にスクロールするときに、必要なときにのみ画像を追加します。画像を追加するときは、ディスクから読み込み、ビューに追加します。水平無限スクロールビューのサンプル コードを見てみましょう: https://code.google.com/p/iphone-infinite-horizo ​​ntal-scroller 。

画像のみを表示するカスタムセルで通常の UITableView を使用することもできます。

于 2013-04-19T09:30:51.147 に答える
1

私は自分の間違いを見つけました。オリジナル/フル画像を 40*40 画像ビューに割り当てていました。それはメモリ警告を生成していました。以下のコードを使用して画像を生成する際に、必要な画像サイズを提供して解決します。

self.generator.maximumSize = CGSizeMake(40, 40);
于 2013-04-23T10:37:41.687 に答える