CGAffineTransform 旋转 90 度

Posted

技术标签:

【中文标题】CGAffineTransform 旋转 90 度【英文标题】:CGAffineTransform Rotation by 90 degrees 【发布时间】:2013-01-02 12:57:11 【问题描述】:

我需要将图像旋转 90 度,即交换宽度和高度(翻转图像)。这需要在我将图像提供给编码器以从中创建视频之前完成。我使用以下代码(参考:How do I export UIImage array as a movie?)

- (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 度的旋转不起作用(由注释指示)。你能找出问题吗?

【问题讨论】:

【参考方案1】:

您正在应用的变换是旋转上下文,问题是原点位于角落而不是上下文的中心。通过将图像旋转 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;

【讨论】:

感谢您的回复。我明白你说的,但是方法还是不行。此外, frameSize 将是图像大小本身。很抱歉造成混淆,我已在发布的代码中进行了更新。 这是我使用的代码:CGContextTranslateCTM(context, CGImageGetHeight(image)/2, CGImageGetWidth(image)/2); CGContextRotateCTM(上下文,M_PI_2); CGContextTranslateCTM(context, -CGImageGetWidth(image)/2, -CGImageGetHeight(image)/2);图像旋转但在旋转时被剪掉一半。 添加了完整的代码。看看这个。您一定是在创建上下文时混淆了大小。 谢谢。它确实有效。你是对的,我把尺寸弄乱了。但是,轮换需要很多时间。

以上是关于CGAffineTransform 旋转 90 度的主要内容,如果未能解决你的问题,请参考以下文章

快速使用 CGAffine 变换旋转视频

UIInterfaceOrientation、CGAffineTransform、框架、边界和中心

使用 CGAffineTransform 旋转后更新 UIImageView 框架时出现奇怪的挤压

css rotate(90deg)是旋转了90度还是旋转到90度

Leecode-48:旋转图像(矩阵顺时针旋转90度)

如何将整个网页旋转90度,180度或270度?