Note that there are some explanatory texts on larger screens.

plurals
  1. POConverting images to Videos iOS5
    primarykey
    data
    text
    <p>I am writing an app that draws on screen and then converts a series of screen grabbed images to videos. However the final video appear a bit off (appears to have rotated).</p> <p>Basically my captured video should draw something like this: <img src="https://i.imgur.com/h56Lc.png" alt="In Simulator:--&gt;"></p> <hr> <p>However it appears to be something like this in the final video: <img src="https://i.imgur.com/TSu6A.png" alt="recorded video:--&gt;"></p> <p>My code is shown below. I'm guessing the problem is in the PixelBuffer logic &amp; that I need to apply some type of a transform. Any suggestions?</p> <pre><code>- (void)exportImages:(NSMutableArray *)imageArray asVideoToPath:(NSString *)path withFrameSize:(CGSize)imageSize framesPerSecond:(NSUInteger)fps { NSFileManager *fileManager = [[NSFileManager alloc] init]; if([fileManager fileExistsAtPath:path]) [fileManager removeItemAtPath:path error:NULL]; NSLog(@"Start building video from defined frames."); NSError *error = nil; AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL: [NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie error:&amp;error]; NSParameterAssert(videoWriter); NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: AVVideoCodecH264, AVVideoCodecKey, [NSNumber numberWithInt:imageSize.width], AVVideoWidthKey, [NSNumber numberWithInt:imageSize.height], AVVideoHeightKey, nil]; AVAssetWriterInput* videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings]; AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput sourcePixelBufferAttributes:nil]; NSParameterAssert(videoWriterInput); NSParameterAssert([videoWriter canAddInput:videoWriterInput]); videoWriterInput.expectsMediaDataInRealTime = YES; [videoWriter addInput:videoWriterInput]; //Start a session: [videoWriter startWriting]; [videoWriter startSessionAtSourceTime:kCMTimeZero]; CVPixelBufferRef buffer = NULL; //convert uiimage to CGImage. int frameCount = 0; for(VideoFrame * frm in imageArray) { UIImage * img = frm._imageFrame; buffer = [self pixelBufferFromCGImage:[img CGImage]]; BOOL append_ok = NO; int j = 0; while (!append_ok &amp;&amp; j &lt; 30) { if (adaptor.assetWriterInput.readyForMoreMediaData) { //print out status:: NSString *border = @"**************************************************"; NSLog(@"\n%@\nProcessing video frame (%d,%d).\n%@",border,frameCount,[imageArray count],border); CMTime frameTime = CMTimeMake(frameCount,(int32_t) fps); append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime]; if(!append_ok){ NSError *error = videoWriter.error; if(error!=nil) { NSLog(@"Unresolved error %@,%@.", error, [error userInfo]); } } } else { printf("adaptor not ready %d, %d\n", frameCount, j); [NSThread sleepForTimeInterval:0.1]; } j++; } if (!append_ok) { printf("error appending image %d times %d\n, with error.", frameCount, j); } frameCount++; } //Finish the session: [videoWriterInput markAsFinished]; [videoWriter finishWriting]; NSLog(@"Write Ended"); </code></pre> <p>}</p> <pre><code>- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image { NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil]; CVPixelBufferRef pxbuffer = NULL; CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, self.frame.size.width, self.frame.size.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, &amp;pxbuffer); if (status != kCVReturnSuccess){ NSLog(@"Failed to create pixel buffer"); } CVPixelBufferLockBaseAddress(pxbuffer, 0); void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer); CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(pxdata, self.frame.size.width, self.frame.size.height, 8, 4*self.frame.size.width, rgbColorSpace, kCGImageAlphaPremultipliedFirst); //kCGImageAlphaNoneSkipFirst); CGContextConcatCTM(context, CGAffineTransformMakeRotation(0)); CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image); CGColorSpaceRelease(rgbColorSpace); CGContextRelease(context); CVPixelBufferUnlockBaseAddress(pxbuffer, 0); return pxbuffer; </code></pre> <p>}</p> <p>FYI: I also tried to save the screen grabbed images to a png file and checked them -- they were all correct. </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload