具有指定大小的 renderInContext 图像绘制
Posted
技术标签:
【中文标题】具有指定大小的 renderInContext 图像绘制【英文标题】:renderInContext image drawing with specified size 【发布时间】:2013-07-31 09:11:45 【问题描述】:如何在不使用 CGAffineTransform 的情况下绘制小于上下文大小的图像?
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
// center image
CGContextTranslateCTM(context, placement.origin.x, placement.origin.y);
[imageView.layer renderInContext:context];
问题在于,如果imageView.image.size
大于size
,它将居中绘制,但在边界处剪切(图像大于绘图区域)。我希望图像适合,所以想减小imageView.image.size
的大小。有没有办法使用renderInContext
来实现这一点?
【问题讨论】:
【参考方案1】:通过[imageView.layer renderInContext:context];
,您无法更改大小(或者我没有找到方法)。这样做的唯一选择是现在使用 drawImage 创建图像(根据请求的大小),分配新的 UIImageView 并绘制其图层。
UIImage *resizedImage = [self createNewImageFrom:currentImage withSize:size];
UIImageView *imageView = [[UIImageView alloc] initWithImage:resizedImage];
// ...
[imageView.layer renderInContext:context];
- (UIImage*)createNewImageFrom:(UIImage*)image withSize:(CGSize)size
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0.0f, size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), image.CGImage);
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
【讨论】:
对否决票有什么意见,或者只是到处乱说?如果我做错了什么,最好告知是什么。 我正在寻找一些方法将图层渲染为不同的大小,最后我找到了方法,您的回答可能会误导其他与我相似的人。【参考方案2】:为什么要在不改变上下文的情况下这样做?这是完成这项工作的最佳工具!
这里最简单的方法是调用CGContextScaleCTM
将比例因子应用于上下文。该比例因子将影响到上下文的所有绘图,包括对-renderIntoContext:
的调用。
【讨论】:
因为上下文已经被转换,我需要它保持原样 - 使用saveCGState
n Restore
也会产生问题。无论如何,我已经找到了解决我的问题的方法并在这里进行了描述,明天会接受这个答案(不能更早)。
如果 CGContextSaveGState
/CGContextRestoreGState
没有恢复上下文的 CTM,那么你做错了什么。您的方法至少使用两倍的内存,并且执行时间至少是转换上下文的两倍。就像我说的:转换上下文是准确适合这项工作的工具。【参考方案3】:
这是缩放尺寸的版本,只需将 scale 替换为 size.width 和 size.height 即可获得任何目标尺寸。
对于 UIView:
-(UIImage*)convertViewToImage:(UIView*)v withScale:(float)scale
//create bitmap context with scaled size
CGSize s = v.bounds.size;
s.width *= scale;
s.height *= scale;
UIGraphicsBeginImageContextWithOptions(s, NO, [UIScreen mainScreen].scale);
//scale CTM to render and resotre CTM
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextScaleCTM(context, scale, scale);
[v.layer renderInContext: context];
CGContextRestoreGState(context);
UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
对于 UIScrollView
-(UIImage*)convertScrollContentToImage:(UIScrollView*)sv withScale:(float)scale
//create bitmap context with scaled size
CGSize s = sv.contentSize;
s.width *= scale;
s.height *= scale;
UIGraphicsBeginImageContextWithOptions(s, NO, [UIScreen mainScreen].scale);
//set scroll.frame.size to contentSize, and contentOffset to 0
CGPoint savedContentOffset = sv.contentOffset;
CGRect savedFrame = sv.frame;
sv.contentOffset = CGPointZero;
sv.frame = CGRectMake(0, 0, sv.contentSize.width, sv.contentSize.height);
//scale CTM to render and resotre CTM
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextScaleCTM(context, scale, scale);
[sv.layer renderInContext: context];
CGContextRestoreGState(context);
//set scroll.frame.size and ContentOffset back
sv.contentOffset = savedContentOffset;
sv.frame = savedFrame;
UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
【讨论】:
CGContextSaveGState 非常消耗内存。我看不出这段代码比我的有任何优势,你能提供任何评论吗?以上是关于具有指定大小的 renderInContext 图像绘制的主要内容,如果未能解决你的问题,请参考以下文章