macos - 使用 CGImageSourceRef 加载图像时旋转错误

标签 macos image-rotation cgimagesource

我使用下面的代码在 C++ 库中加载图像。加载某些图像时,图像的旋转是错误的。它似乎会影响来自 iPhone 相机的 JPEG。我该如何解决?

据推测,某处有一个标志为相机捕获的 JPEG 设置。我不确定以这种方式加载图像时如何访问它。

CGImageSourceRef source = CGImageSourceCreateWithURL(url, NULL);
CFRelease(url);

if(source==NULL)
    return IM_ErrFileError;

CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL);
CFRelease(source);

if(image==NULL)
    return IM_ErrFileError;

int w = (int)CGImageGetWidth(image);
int h = (int)CGImageGetHeight(image);

im::Err err = img.Create(im::IntSize(w, h), bands, sizeof(uint8_t), imgtype);
if(IM_FAILED(err))
{
    CGImageRelease(image);
    return err;
}

img.Clear();

CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(colorspacename);
if(colorSpace==NULL)
{
    CGImageRelease(image);
    return IM_ErrAlloc;
}

// Create RGBA context
CGContextRef context = CGBitmapContextCreate(img.BytePtr(), w, h, 8, img.StrideBytes(), colorSpace, alphainfo);

if(context==NULL)
{
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(image);
    return IM_ErrAlloc;
}

CGColorSpaceRelease(colorSpace);

CGRect rect;

rect.origin.x = 0;
rect.origin.y = 0;
rect.size.width = w;
rect.size.height = h;

CGContextDrawImage(context, rect, image);

CGContextRelease(context);
CGImageRelease(image);

根据答案,这是我修改代码的方式。首先获取方向:
int orientation = 1;

CFDictionaryRef dict = CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
if(dict)
{
    CFNumberRef imageOrientation;

    if(CFDictionaryGetValueIfPresent(dict, kCGImagePropertyOrientation, (const void **)&imageOrientation))
    {
        if(imageOrientation)
            CFNumberGetValue(imageOrientation, kCFNumberIntType, &orientation);
    }

    CFRelease(dict);
}

确保尺寸正确:
int width = (int)CGImageGetWidth(image);
int height = (int)CGImageGetHeight(image);

int canvasw, canvash;

if(orientation<=4)
{
    canvasw = width;
    canvash = height;
}
else
{
    canvasw = height;
    canvash = width;
}

使用 Canvas 大小创建位图上下文图像。渲染时补偿方向:
switch(orientation)
{
    case 2:
        // 2 = 0th row is at the top, and 0th column is on the right - Flip Horizontal
        CGContextConcatCTM(context, CGAffineTransformMake(-1.0, 0.0, 0.0, 1.0, width, 0.0));
        break;

    case 3:
        // 3 = 0th row is at the bottom, and 0th column is on the right - Rotate 180 degrees
        CGContextConcatCTM(context, CGAffineTransformMake(-1.0, 0.0, 0.0, -1.0, width, height));
        break;

    case 4:
        // 4 = 0th row is at the bottom, and 0th column is on the left - Flip Vertical
        CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0, -1.0, 0.0, height));
        break;

    case 5:
        // 5 = 0th row is on the left, and 0th column is the top - Rotate -90 degrees and Flip Vertical
        CGContextConcatCTM(context, CGAffineTransformMake(0.0, -1.0, -1.0, 0.0, height, width));
        break;

    case 6:
        // 6 = 0th row is on the right, and 0th column is the top - Rotate 90 degrees
        CGContextConcatCTM(context, CGAffineTransformMake(0.0, -1.0, 1.0, 0.0, 0.0, width));
        break;

    case 7:
        // 7 = 0th row is on the right, and 0th column is the bottom - Rotate 90 degrees and Flip Vertical
        CGContextConcatCTM(context, CGAffineTransformMake(0.0, 1.0, 1.0, 0.0, 0.0, 0.0));
        break;

    case 8:
        // 8 = 0th row is on the left, and 0th column is the bottom - Rotate -90 degrees
        CGContextConcatCTM(context, CGAffineTransformMake(0.0, 1.0, -1.0, 0.0, height, 0.0));
        break;

    default:
        break;
}

最佳答案

我实际上还没有用 iPhone 图像尝试过这个,但我建议使用 CGImageSourceCopyPropertiesAtIndex获取 kCGImagePropertyOrientation .一旦知道正确的方向,就可以在绘制时应用一些变换。

关于macos - 使用 CGImageSourceRef 加载图像时旋转错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24839617/

相关文章:

ios - Xcode 5 崩溃——Xcode 意外退出

android - 当点击一个按钮在android中顺时针旋转图像

javascript - Caman.js 渲染适用于以前的状态而不是 Canvas 的当前状态

php - 如何在 osx 机器上安装 "locale"以在 php 中使用?

macos - 变量在 Bash 中用 "echo"覆盖文本问题

php - 以透明颜色旋转图像

objective-c - 如何从图像原始数据创建 CGImageSourceRef?

ios - 当我在 Swift 中使用 CGImageSourceCreateThumbnailAtIndex 时应用程序崩溃

c++ - LLDB - Qt 缺少调试信息