在 iOS 4 中保存 UIView 内容,其中包含图像的实际大小(即放大内容以进行保存)

StackOverflow https://stackoverflow.com/questions/4213529

我有一个 UIView,其中有许多 UIImageView 作为子视图。该应用程序在 iOS4 上运行,我使用具有视网膜显示分辨率的图像(即图像加载比例 = 2)

我想保存 UIView 的内容...但 ...里面有图像的真实尺寸。IE。视图的大小为 200x200,内部的图像比例为 2,我想保存 400x400 的结果图像以及所有实际大小的图像。

现在首先想到的是创建一个新的图像上下文并再次加载内部所有图像的比例=1,这应该可以,但我想知道是否有更优雅的方法来做到这一点?似乎需要大量内存和处理器时间来重新加载所有内容,因为它已经完成了......

附注如果有人有答案 - 包括代码会很好

有帮助吗?

解决方案

用于渲染的实施任何的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框架薄弱环节,请点击左侧导航项目项,单击该项目的目标 - >生成阶段 - >链接二进制,然后选择“可选”(弱)在UIKit框架类型

下面是与的UIColor,UIImage的,NSArray中,类似的NSDictionary扩展,...

其他提示

我已经执行了这样的操作,将 MKMapView 中的引脚保存为 PNG 文件(在视网膜显示中): MKPinAnnotationView:有超过三种颜色可供选择吗?

这是执行保存的关键部分的摘录 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; }

的关键是,到UIGraphicsBeginImageContextWithOptions第三个参数是尺度,它决定如何将图像最终将被写出。

如果你总是想真正的像素尺寸,使用[UIScreen mainScreen]规模]得到屏幕的当前规模:

UIGraphicsBeginImageContextWithOptions(viewSizeInPoints, YES, [[UIScreen mainScreen] scale]);

如果您iPhone4上使用标度= 1.0,将得到的图像,其在尺寸,结果是从真像素计数按比例缩小。如果手动写出来的图像到640x960的尺寸(例如:通过像素作为第一个参数),它实际上是被缩减了约一样可怕,你想象它看起来看起来会按比例缩小图片

你不能只是建立在所需大小的新的图形上下文,使用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();

导入QuartzCore(点击主体工程,构建阶段,进口),并在你需要它添加:

#import <QuartzCore/QuartzCore.h>

我imageViews是属性,如果不是,则忽略.self和imageViews传递到该功能的参数,然后呼叫renderInContext在两个图像上在一个新的UIGraphicsCurrentContext

- (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;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top