4

以下のコードを使用して、一連のUIImageを取得し、それらをmovに変換しています。どういうわけか、風景写真かポートレート写真かに応じて、下部または右側に緑色の境界線が表示され続けます。画像は215x320です。

緑の境界線を削除するにはどうすればよいですか?UIImagesから.movを作成するより良い方法はありますか?

- (void)createMov
{
  UIImage *first = [self.videoFrames objectAtIndex:0];

  CGSize frameSize = first.size;

  NSError *error = nil;
  AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
                                [NSURL fileURLWithPath:fileName] fileType:AVFileTypeQuickTimeMovie
                                                        error:&error];

  if (error) {
    NSLog(@"error creating AssetWriter: %@",[error description]);
  }

  int numPixels = first.size.width * first.size.height;
  int bitsPerSecond = numPixels * 11.04;


  NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                 AVVideoCodecH264, AVVideoCodecKey,
                                 [NSNumber numberWithInt:frameSize.width], AVVideoWidthKey,
                                 [NSNumber numberWithInt:frameSize.height], AVVideoHeightKey,
                                 [NSDictionary dictionaryWithObjectsAndKeys:
                                  [NSNumber numberWithInteger:bitsPerSecond], AVVideoAverageBitRateKey,
                                  [NSNumber numberWithInteger:30], AVVideoMaxKeyFrameIntervalKey,
                                  nil], AVVideoCompressionPropertiesKey,
                                 nil];

  AVAssetWriterInput* writerInput = [[AVAssetWriterInput
                                      assetWriterInputWithMediaType:AVMediaTypeVideo
                                      outputSettings:videoSettings] retain];

  NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
  [attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB] forKey:   (NSString*)kCVPixelBufferPixelFormatTypeKey];
  [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.width] forKey:(NSString*)kCVPixelBufferWidthKey];
  [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.height] forKey:(NSString*)kCVPixelBufferHeightKey];

  AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
                                              assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
                                               sourcePixelBufferAttributes:attributes];

  [videoWriter addInput:writerInput];

  // fixes all errors
  writerInput.expectsMediaDataInRealTime = YES;

  //Start a session:
  BOOL start = [videoWriter startWriting];
  NSLog(@"Session started? %d", start);
  [videoWriter startSessionAtSourceTime:kCMTimeZero];


  // Writing.
  CVPixelBufferRef buffer = NULL;
  buffer = [self pixelBufferFromCGImage:[first CGImage]];
  BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];

  if (result == NO) //failes on 3GS, but works on iphone 4
    NSLog(@"failed to append buffer");

  if(buffer)
    CVBufferRelease(buffer);

  [NSThread sleepForTimeInterval:0.05];

  int fps = [Utils frameRate];

  int i = 0;
  for (UIImage *imgFrame in self.videoFrames) {
    i = [self addFrame:adaptor videoWriter:videoWriter buffer:buffer imgFrame:imgFrame i:i fps:fps];
  }

  //Finish the session:
  [writerInput markAsFinished];
  [videoWriter finishWriting];
  CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
  [videoWriter release];
  [writerInput release];
}


- (int)addFrame:(AVAssetWriterInputPixelBufferAdaptor *)adaptor videoWriter:(AVAssetWriter *)videoWriter buffer:(CVPixelBufferRef)buffer imgFrame:(UIImage *)imgFrame i:(int)i fps:    (float)fps
{
  if (adaptor.assetWriterInput.readyForMoreMediaData) {

    i++;
    NSLog(@"inside for loop %d",i);
    CMTime frameTime = CMTimeMake(1, fps);
    CMTime lastTime=CMTimeMake(i, fps);
    CMTime presentTime=CMTimeAdd(lastTime, frameTime);

    buffer = [self pixelBufferFromCGImage:[imgFrame CGImage]];
    BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];

    if (result == NO) { //fails on 3GS, but works on iphone 4
      NSLog(@"failed to append buffer");
      NSLog(@"The error is %@", [videoWriter error]);
    }

    if (buffer) {
      CVBufferRelease(buffer);
    }

    [NSThread sleepForTimeInterval:0.05];
  } else {
    NSLog(@"error");
    i--;
  }
  [NSThread sleepForTimeInterval:0.02];

  return i;
}


- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image
{
  NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                           [NSNumber numberWithBool:YES],     kCVPixelBufferCGImageCompatibilityKey,
                           [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                           nil];
  CVPixelBufferRef pxbuffer = NULL;

  CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image),
                      CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
                  &pxbuffer);

  CVPixelBufferLockBaseAddress(pxbuffer, 0);
  void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
  size_t rowBytes = CVPixelBufferGetBytesPerRow(pxbuffer);


  CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image),
                                           CGImageGetHeight(image), 8, rowBytes, rgbColorSpace,
                                           kCGImageAlphaNoneSkipFirst);

  CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));


  CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                     CGImageGetHeight(image)), image);
  CGColorSpaceRelease(rgbColorSpace);
  CGContextRelease(context);

  CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

  return pxbuffer;
}
4

1 に答える 1