CGAffineTransform Поворот на 90 градусов

Мне нужно повернуть изображение на 90 градусов, то есть поменять местами ширину и высоту (перевернуть изображение). Это нужно сделать до того, как я скармливаю изображение кодировщику для создания из него видео. Я использую следующий код (Ссылка: Как сделать Я экспортирую массив UIImage как фильм?)

- (CVPixelBufferRef) newPixelBufferFromCGImage: (CGImageRef) image
{
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
        [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
        nil];
    CVPixelBufferRef pxbuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image),
        CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (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, CGImageGetWidth(image),
        CGImageGetHeight(image), 8, 4*CGImageGetWidth(image), rgbColorSpace, 
        kCGImageAlphaNoneSkipFirst);
    NSParameterAssert(context);
    CGContextConcatCTM(context, CGAffineTransformMakeRotation(1.571)); // ROTATION
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
        CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}

Однако поворот на 90 градусов не работает (обозначено комментарием). Не могли бы вы определить проблему?


person Hrishikesh_Pardeshi    schedule 02.01.2013    source источник


Ответы (1)


Применяемое преобразование IS вращает контекст, проблема в том, что начало координат находится в углу, а не в центре контекста. Поворачивая изображение на 90 градусов, вы полностью перемещаете его к отрицательной границе и, следовательно, ничего не видите. Предполагая, что в вашем коде frameSize - это размер повернутого изображения (с инвертированной шириной / высотой), вам нужно переместить это начало в центр и применить там поворот. Пытаться:

CGContextTranslateCTM(context, frameSize.width / 2, frameSize.height / 2);
CGContextRotateCTM(context, M_PI_2);
CGContextTranslateCTM(context, -frameSize.height / 2, -frameSize.width / 2);
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);


- (CVPixelBufferRef) newPixelBufferFromCGImage: (CGImageRef) image
{
    CGSize frameSize = CGSizeMake(CGImageGetHeight(image), CGImageGetWidth(image));
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
        [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
        nil];
    CVPixelBufferRef pxbuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width,
        frameSize.height, kCVPixelFormatType_32ARGB, (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, frameSize.width,
        frameSize.height, 8, 4 * frameSize.width, rgbColorSpace, 
        kCGImageAlphaNoneSkipFirst);
    NSParameterAssert(context);
    CGContextTranslateCTM(context, frameSize.width / 2, frameSize.height / 2);
    CGContextRotateCTM(context, M_PI_2);
    CGContextTranslateCTM(context, -frameSize.height / 2, -frameSize.width / 2);
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);

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

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}
person Fernando Mazzon    schedule 02.01.2013
comment
Спасибо за ответ. Я понимаю, что вы говорите, но метод по-прежнему не работает. Кроме того, frameSize будет размером самого изображения. Извините за путаницу, я обновил опубликованный код. - person Hrishikesh_Pardeshi; 03.01.2013
comment
Это код, который я использую: CGContextTranslateCTM (context, CGImageGetHeight (image) / 2, CGImageGetWidth (image) / 2); CGContextRotateCTM (контекст, M_PI_2); CGContextTranslateCTM (контекст, -CGImageGetWidth (изображение) / 2, -CGImageGetHeight (изображение) / 2); Изображение вращается, но при повороте обрезается наполовину. - person Hrishikesh_Pardeshi; 03.01.2013
comment
Добавил полный код. Проверить это. Вы, должно быть, перепутали размер при создании контекста. - person Fernando Mazzon; 03.01.2013
comment
Спасибо. Это действительно работает. Вы были правы, я испортил размер. Но на ротацию уходит много времени. - person Hrishikesh_Pardeshi; 04.01.2013