我有一个UIView,其中包含许多UIImageViews作为子视图。该应用程序在iOS4上运行,我使用具有视网膜显示分辨率的图像(即图像加载比例= 2)
我想要保存UIView的内容...但是...内部有真实的图像大小。即视图的大小为200x200,内部有scale = 2的图像,我想保存400x400的结果图像以及所有图像的真实大小。
现在首先想到的是创建一个新的图像上下文并再次加载scale = 1的内部所有图像,这应该做,但我想知道是否有更优雅的方法来做到这一点?看起来像是内存的腰部和处理器时间再次重新加载所有东西,因为它已经完成......
P.S。如果有人有答案 - 包括代码会很好
答案 0 :(得分:25)
将任何UIView 呈现为图像的实现(也适用于视网膜显示)。
helper.h文件:
@interface UIView (Ext)
- (UIImage*) renderToImage;
@end
和helper.m文件中的所属实现:
#import <QuartzCore/QuartzCore.h>
@implementation UIView (Ext)
- (UIImage*) renderToImage
{
// IMPORTANT: using weak link on UIKit
if(UIGraphicsBeginImageContextWithOptions != NULL)
{
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0);
} else {
UIGraphicsBeginImageContext(self.frame.size);
}
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
0.0是比例因子。要应用于位图的比例因子。如果指定值0.0,则比例因子将设置为设备主屏幕的比例因子。
QuartzCore.framework 也应放入项目中,因为我们在图层对象上调用函数。
要在UIKit框架上启用弱链接,请单击左侧导航器中的项目项,单击项目目标 - &gt;构建阶段 - &gt;链接二进制文件并在UIKit框架上选择“可选”(弱)类型。
以下是library,其中包含类似UIColor,UIImage,NSArray,NSDictionary,...的扩展名。
答案 1 :(得分:4)
我已经执行了将MKMapView中的引脚保存为PNG文件(在视网膜显示中):MKPinAnnotationView: Are there more than three colors available?
以下是使用其视网膜定义执行UIView
(theView
)保存的关键部分的摘录:
-(void) saveMyView:(UIView*)theView { //The image where the view content is going to be saved. UIImage* image = nil; UIGraphicsBeginImageContextWithOptions(theView.frame.size, NO, 2.0); [theView.layer renderInContext: UIGraphicsGetCurrentContext()]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); NSData* imgData = UIImagePNGRepresentation(image); NSString* targetPath = [NSString stringWithFormat:@"%@/%@", [self writablePath], @"thisismyview.png" ]; [imgData writeToFile:targetPath atomically:YES]; }
-(NSString*) writablePath { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; return documentsDirectory; }
答案 2 :(得分:2)
关键是UIGraphicsBeginImageContextWithOptions的第三个参数是 scale ,它确定最终如何写出图像。
如果您一直想要实际像素尺寸,请使用[[UIScreen主屏幕]比例]获取屏幕的当前比例:
UIGraphicsBeginImageContextWithOptions(viewSizeInPoints, YES, [[UIScreen mainScreen] scale]);
如果您在iPhone4上使用scale = 1.0,您将获得一个尺寸为 points 的图像,结果将从真实的像素数量缩小。如果您手动将图像写入640x960尺寸(例如:将像素作为第一个参数传递),它实际上将是按比例缩小的缩小图像,看起来像您想象的那样糟糕。
答案 3 :(得分:0)
难道你不能只创建一个所需大小的新图形上下文,使用CGAffineTransform缩小它,渲染根UIView的根层,将上下文恢复到原始大小并渲染图像?没有试过这个视网膜内容,但这似乎适用于在UIImageViews中缩小的大图像...
类似的东西:
CGSize originalSize = myOriginalImage.size; //or whatever
//create context
UIGraphicsBeginImageContext(originalSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context); //1 original context
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, originalSize.height);
CGContextScaleCTM(context, 1.0, -1.0);
//original image
CGContextDrawImage(context, CGRectMake(0,0,originalSize.width,originalSize.height), myOriginalImage.CGImage);
CGContextRestoreGState(context);//1 restore to original for UIView render;
//scaling
CGFloat wratio = originalSize.width/self.view.frame.size.width;
CGFloat hratio = originalSize.height/self.view.frame.size.height;
//scale context to match view size
CGContextSaveGState(context); //1 pre-scaled size
CGContextScaleCTM(context, wratio, hratio);
//render
[self.view.layer renderInContext:context];
CGContextRestoreGState(context);//1 restore to pre-scaled size;
UIImage *exportImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
答案 4 :(得分:0)
导入QuartzCore(单击主项目,构建阶段,导入)以及您需要的位置添加:
#import <QuartzCore/QuartzCore.h>
我的imageViews是属性,如果不是,请忽略.self
并将imageViews作为参数传递给函数,然后在新renderInContext
<中的两个图像上调用UIGraphicsCurrentContext
/ p>
- (UIImage *)saveImage
{
UIGraphicsBeginImageContextWithOptions(self.mainImage.bounds.size, NO, 0.0);
[self.backgroundImage.layer renderInContext:UIGraphicsGetCurrentContext()];
[self.mainImage.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *savedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return savedImage;
}