You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS17中CGImageSourceCreateThumbnailAtIndex旋转功能失效求助

iOS 17 下 CGImageSourceCreateThumbnailAtIndex 旋转失效的解决办法

问题背景

通过 CGImageSourceCreateThumbnailAtIndex 生成缩略图时,在 options 中指定 kCGImagePropertyOrientation 控制旋转的逻辑,在 iOS 17 上完全失效——无论设置 kCGImagePropertyOrientationUp、Left、Down 还是 Right,返回的图片方向均无变化。但该逻辑在 iOS 16 及以下系统、iPadOS 17 中均可正常运行。

问题根源

iOS 17 对 CGImageSourceCreateThumbnailAtIndex 的参数处理逻辑做了变更:kCGImagePropertyOrientation 现在仅用于读取图片元数据中的原始方向,不再支持通过该参数强制指定旋转角度。这个调整是苹果统一图片方向处理逻辑的一部分,目前仅在 iOS 17 生效,iPadOS 17 暂未跟进该变更。

修复方案

方案1:生成缩略图后手动旋转

先生成基础缩略图,再通过 UIImage 的 orientation 属性应用旋转:

CGImageSourceRef imageSource = CGImageSourceCreateWithData(capturedImage, nil);
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
    (id)kCGImageSourceCreateThumbnailWithTransform: @YES,
    (id)kCGImageSourceCreateThumbnailFromImageAlways : @YES,
    (id)kCGImageSourceThumbnailMaxPixelSize : @(maxPixelSize)
};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options);
CFRelease(imageSource);

// 手动应用旋转
UIImage *rotatedImage = [[UIImage alloc] initWithCGImage:thumbnail 
                                                   scale:1.0 
                                             orientation:rotationAngle];
CGImageRef finalThumbnail = rotatedImage.CGImage;
CFRetain(finalThumbnail); // 按需管理内存,避免泄漏
CFRelease(thumbnail);
return finalThumbnail;

方案2:用 CIImage 统一处理缩放与旋转

通过 CIImage 管道同时完成缩放和旋转,兼容性更强:

CIImage *ciImage = [CIImage imageWithData:capturedImage];
CGFloat scaleFactor = MIN(maxPixelSize / ciImage.extent.size.width, 
                          maxPixelSize / ciImage.extent.size.height);

// 根据目标方向构建变换矩阵
CGAffineTransform transform = CGAffineTransformIdentity;
switch (rotationAngle) {
    case kCGImagePropertyOrientationLeft:
        transform = CGAffineTransformRotate(transform, M_PI_2);
        transform = CGAffineTransformTranslate(transform, 0, -ciImage.extent.size.width);
        break;
    case kCGImagePropertyOrientationDown:
        transform = CGAffineTransformRotate(transform, M_PI);
        transform = CGAffineTransformTranslate(transform, -ciImage.extent.size.width, -ciImage.extent.size.height);
        break;
    case kCGImagePropertyOrientationRight:
        transform = CGAffineTransformRotate(transform, -M_PI_2);
        transform = CGAffineTransformTranslate(transform, -ciImage.extent.size.height, 0);
        break;
    default:
        break;
}

// 应用旋转和缩放
CIImage *transformedImage = [ciImage imageByApplyingTransform:transform];
transformedImage = [transformedImage imageByApplyingTransform:CGAffineTransformMakeScale(scaleFactor, scaleFactor)];

// 转换为 CGImage
CIContext *context = [CIContext contextWithOptions:nil]; // 建议全局复用 CIContext 提升性能
CGImageRef finalThumbnail = [context createCGImage:transformedImage fromRect:transformedImage.extent];
return finalThumbnail;

兼容建议

如果需要同时兼容新旧系统,可以通过系统版本判断分支处理:

if (@available(iOS 17.0, *)) {
    // 使用上述修复方案
} else {
    // 保留原有逻辑
    CGImageSourceRef imageSource = CGImageSourceCreateWithData(capturedImage, nil);
    CFDictionaryRef options = (__bridge CFDictionaryRef) @{
        (id)kCGImageSourceCreateThumbnailWithTransform: @YES,
        (id)kCGImageSourceCreateThumbnailFromImageAlways : @YES,
        (id)kCGImageSourceThumbnailMaxPixelSize : @(maxPixelSize),
        (id)kCGImagePropertyOrientation: @(rotationAngle)
    };
    CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options);
    CFRelease(imageSource);
    return thumbnail;
}

内容的提问来源于stack exchange,提问作者Tedxxxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:15:58