IOS 5: UIView преобразован в видео, и полученное видео повреждено - PullRequest
1 голос
/ 23 января 2012

Я хочу получить UIView, преобразовать в изображение и затем сохранить это изображение в видеофайле (.mp4).Я использую следующую часть кода, которая захватывает изображение и помещает его в буфер пикселей:

BOOL appended;
    if(input.readyForMoreMediaData==YES){
        //grab the view and convert it into image
        CGSize imgsize=self.imageSource.frame.size;
        UIGraphicsBeginImageContext(imgsize);
        [self.imageSource.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage* grabbedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        CVReturn cvErr = kCVReturnSuccess;
        CGImageRef image = (CGImageRef) [grabbedImage CGImage];

        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                                 [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                                 nil];
        CVPixelBufferRef pxbuffer = NULL;

        CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, imgsize.width,
                                              imgsize.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, 
                                              &pxbuffer);

        NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

        CVPixelBufferLockBaseAddress(pxbuffer, 0);
        void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
        NSParameterAssert(pxdata != NULL);

        CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(pxdata, imgsize.width,
                                                     imgsize.height, 8, 4*imgsize.width, rgbColorSpace, 
                                                     kCGImageAlphaNoneSkipFirst);
        NSParameterAssert(context);
        CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
        CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
                                               CGImageGetHeight(image)), image);
        CGColorSpaceRelease(rgbColorSpace);
        CGContextRelease(context);

        CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

        appended = [pxlBufAdaptor appendPixelBuffer:pxbuffer withPresentationTime:presentationTime];
        CVBufferRelease(pxbuffer );
    }

Проблема в том, что полученное видео содержит поврежденное изображение - все пиксели смещены.Похоже, что память заполнена байтами с некоторым смещением, и это смещение портит представление.

Как это можно исправить?Я хотел бы иметь любой клей или направление.Заранее спасибо.

1 Ответ

3 голосов
/ 23 января 2012

Это выглядит подозрительно:

CGContextRef context = CGBitmapContextCreate(pxdata, imgsize.width,
    imgsize.height, 8, 4*imgsize.width, rgbColorSpace, 
    kCGImageAlphaNoneSkipFirst);

Вы вычисляете параметр bytesPerRow на основе ширины изображения, а не запрашиваете pxbuffer его байтов на строку.Попробуйте это:

CGContextRef context = CGBitmapContextCreate(pxdata, imgsize.width,
    imgsize.height, 8, CVPixelBufferGetBytesPerRow(pxbuffer),
    rgbColorSpace, kCGImageAlphaNoneSkipFirst);

Кроме того, кажется неэффективным создавать контекст растровой графики с UIGraphicsGetCurrentContext, рендерить слой в контекст, получать изображение из контекста, уничтожать контекст, создавать буфер пикселейсоздайте контекст растровой графики, используя буфер пикселей, и нарисуйте изображение слоя в новом контексте.Почему бы не заменить ваш CGContextDrawImage звонок на [self.imageSource.layer renderInContext:context]?

...