作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
当我用大图像(即 > 10 MB)测试时,以下创建缩略图的方法在 iPad 上崩溃。我已经对它进行了概要分析,Allocations 没有报告任何大的内存峰值 - 它在操作期间始终保持在 5 MB 的事件内存。
如何为如此大的图像创建缩略图?我试过使用 Core Graphics 对其进行缩放,但内存效率较低且不起作用。
+(UIImage*) thumbnailImageAtPath:(NSString*) path withSize:(CGSize) size{
@autoreleasepool{
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:path], NULL);
if(!src){
return nil;
}
NSDictionary* options = @{
(id)kCGImageSourceShouldAllowFloat : (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailWithTransform : (id)kCFBooleanFalse,
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent : (id)kCFBooleanTrue,
(id)kCGImageSourceThumbnailMaxPixelSize : [NSNumber numberWithDouble:1024]
};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)options);
// Doesn't reach here :(
UIImage* img = [[UIImage alloc] initWithCGImage:thumbnail];
NSLog(@"Size: %f, %f", size.width, size.height);
CGImageRelease(thumbnail);
CFRelease(src);
return img;
}
}
我已经在主线程、工作线程、并发、非并发等上尝试过它——它似乎在实际设备上不起作用。
同样奇怪的是,它可以出色地处理 > 60 MB 的 PDF。
最佳答案
尝试删除选项 kCGImageSourceThumbnailMaxPixelSize...如果没有请问我。
编辑:试试这个代码:
+ (UIImage*)scaleAndRotateImage:(UIImage *)image{
int kMaxResolution = 1024; // Or whatever 320
CGImageRef imgRef = image.CGImage;
CGFloat width;
CGFloat height;
width = CGImageGetWidth(imgRef);
height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution) {
CGFloat ratio = width/height;
if (ratio > 1) {
bounds.size.width = kMaxResolution;
bounds.size.height = bounds.size.width / ratio;
}
else {
bounds.size.height = kMaxResolution;
bounds.size.width = bounds.size.height * ratio;
}
}
CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = image.imageOrientation;
switch(orient) {
case UIImageOrientationUp: //EXIF = 1
transform = CGAffineTransformIdentity;
break;
case UIImageOrientationUpMirrored: //EXIF = 2
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
break;
case UIImageOrientationDown: //EXIF = 3
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationDownMirrored: //EXIF = 4
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;
case UIImageOrientationLeftMirrored: //EXIF = 5
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationLeft: //EXIF = 6
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationRightMirrored: //EXIF = 7
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
case UIImageOrientationRight: //EXIF = 8
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
default:
[NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
}
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -height, 0);
}
else {
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
}
CGContextConcatCTM(context, transform);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageCopy;}
关于ios - CGImageSourceCreateThumbnailAtIndex 崩溃与 20MB 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18770928/
当我用大图像(即 > 10 MB)测试时,以下创建缩略图的方法在 iPad 上崩溃。我已经对它进行了概要分析,Allocations 没有报告任何大的内存峰值 - 它在操作期间始终保持在 5 MB 的
我只是使用CGImageSourceCreateThumbnailAtIndex来缩小UIImage尺寸。我收到崩溃消息: "IIONumber -- 'num' is not a CFNumberR
我想使用函数 CGImageSourceCreateThumbnailAtIndex 从 UIImage 创建缩略图。我所拥有的只是 UIImage 本身。该图像是 UIView 上的快照。 拜托,我
我是一名优秀的程序员,十分优秀!