2012-01-12 24 views
1

我的iPad应用程序有一个导航,我显示不同页面的屏幕截图,因为我想一次显示多个屏幕截图,我将容器缩放到原始屏幕截图的24%左右(1024×768)。当包含UIView时UIImage/UIImageView重绘缩放

- (void) loadView 
{ 
    // get landscape screen frame 
    CGRect screenFrame = [UIScreen mainScreen].bounds; 
    CGRect landscapeFrame = CGRectMake(0, 0, screenFrame.size.height, screenFrame.size.width); 

    UIView *view = [[UIView alloc] initWithFrame:landscapeFrame]; 
    view.backgroundColor = [UIColor grayColor]; 

    self.view = view; 

    // add container view for 2 images 
    CGRect startFrame = CGRectMake(-landscapeFrame.size.width/2, 0, landscapeFrame.size.width*2, landscapeFrame.size.height); 
    container = [[UIView alloc] initWithFrame:startFrame]; 
    container.backgroundColor = [UIColor whiteColor]; 

    // add image 1 (1024x768) 
    UIImage *img1 = [UIImage imageNamed:@"01.jpeg"]; 
    UIImageView *img1View = [[UIImageView alloc] initWithImage:img1]; 
    [container addSubview:img1View]; 

    // add image 2 (1024x768) 
    UIImage *img2 = [UIImage imageNamed:@"02.jpeg"]; 
    UIImageView *img2View = [[UIImageView alloc] initWithImage:img2]; 

    // move img2 to the right of img1 
    CGRect newFrame = img2View.frame; 
    newFrame.origin.x = 1024.0; 
    img2View.frame = newFrame; 

    [container addSubview:img2View]; 

    // scale to 24% 
    container.transform = CGAffineTransformMakeScale(0.24, 0.24); 

    [self.view addSubview:container]; 
} 

但是当我缩放图像与“小”的文字看上去某事像这样:

我必须使用大屏幕截图,因为如果用户点击图片,应该扩展到100%,清脆。

有没有一种方法可以在不损坏性能的情况下“顺利”(即时)调整图像? 它有足够的两个版本:完整的一个和另一个为24%的版本。

回答

3

缩小图像看起来很糟糕的原因是在OpenGL中使用快速但低质量的线性插值缩放。正如你可能知道的那样,UIView建立在CALayer的基础之上,而CALayer又是一种OpenGL纹理的包装。因为图层的内容驻留在视频卡中,所以CALayer可以在GPU上完成所有的魔术,而不管CPU是忙于加载网站还是阻止磁盘访问等等。我只提到这一点,因为注意图层中纹理的实际内容是有用的。在你的情况下,UIImageView的图层在其纹理上具有完整的1024x768位图图像,并且不受容器转换的影响:UIImageView中的CALayer没有看到它将会变成(让我们看看..)246x185 on并且重新缩放它的位图,它只是让OpenGL做它的事情,并且每次更新显示时缩小位图的大小。

为了获得更好的缩放比例,我们需要在CoreGraphics而不是OpenGL中完成。下面是做这件事:

- (UIImage*)scaleImage:(UIImage*)image by:(float)scale 
{ 
    CGSize size = CGSizeMake(image.size.width * scale, image.size.height * scale); 
    UIGraphicsBeginImageContextWithOptions(size, YES, 0.0); 
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return imageCopy; 
} 

- (void)loadView 
{ 
    // get landscape screen frame 
    CGRect screenFrame = [UIScreen mainScreen].bounds; 
    CGRect landscapeFrame = CGRectMake(0, 0, screenFrame.size.height, screenFrame.size.width); 

    UIView *view = [[UIView alloc] initWithFrame:landscapeFrame]; 
    view.backgroundColor = [UIColor grayColor]; 

    self.view = view; 

    // add container view for 2 images 
    CGRect startFrame = CGRectMake(-landscapeFrame.size.width/2, 0, landscapeFrame.size.width*2, landscapeFrame.size.height); 
    container = [[UIView alloc] initWithFrame:startFrame]; 
    container.backgroundColor = [UIColor whiteColor]; 

    // add image 1 (1024x768) 
    UIImage *img1 = [UIImage imageNamed:@"01.png"]; 
    img1View = [[TapImageView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)]; 
    img1View.userInteractionEnabled = YES; // important! 
    img1View.image = [self scaleImage:img1 by:0.24]; 
    [container addSubview:img1View]; 

    // add image 2 (1024x768) 
    UIImage *img2 = [UIImage imageNamed:@"02.png"]; 
    img2View = [[TapImageView alloc] initWithFrame:CGRectMake(1024, 0, 1024, 768)]; 
    img2View.userInteractionEnabled = YES; 
    img2View.image = [self scaleImage:img2 by:0.24]; 
    [container addSubview:img2View]; 

    // scale to 24% and layout subviews 
    zoomed = YES; 
    container.transform = CGAffineTransformMakeScale(0.24, 0.24); 

    [self.view addSubview:container]; 
} 

- (void)viewTapped:(id)sender 
{ 
    zoomed = !zoomed; 

    [UIView animateWithDuration:0.5 animations:^ 
    { 
     if (zoomed) 
     { 
      container.transform = CGAffineTransformMakeScale(0.24, 0.24); 
     } 
     else 
     { 
      img1View.image = [UIImage imageNamed:@"01.png"]; 
      img2View.image = [UIImage imageNamed:@"02.png"]; 
      container.transform = CGAffineTransformMakeScale(1.0, 1.0); 
     } 
    } 
    completion:^(BOOL finished) 
    { 
     if (zoomed) 
     { 
      UIImage *img1 = [UIImage imageNamed:@"01.png"]; 
      img1View.image = [self scaleImage:img1 by:0.24]; 
      UIImage *img2 = [UIImage imageNamed:@"02.png"]; 
      img2View.image = [self scaleImage:img2 by:0.24]; 
     } 
    }]; 
} 

而这里的TapImageView,一个UIImageView子类,它告诉我们,当它已经通过发送行动起来响应链挖掘:

@interface TapImageView : UIImageView 
@end 

@implementation TapImageView 

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    [[UIApplication sharedApplication] sendAction:@selector(viewTapped:) to:nil from:self forEvent:event]; 
} 

@end 
1

而不是缩放容器及其所有子视图。从容器的内容创建一个UIImageView并将其框架大小调整为原始大小的24%。

UIGraphicsBeginImageContext(container.bounds.size); 
[container renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *containerImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

UIImageView *containerImageView = [[UIImageView alloc] initWithImage:containerImage]; 
CGRectFrame containerFrame = startFrame; 
containerFrame.size.with *= 0.24; 
containerFrame.size.height *= 0.24; 
containerImageView.frame = containerFrame; 

[self.view addSubView:containerImageView]; 
+0

我简化了代码位。但因为截图应该是(种)互动,我不能只是从所有的截图创建一个大的图像:( – pkyeck 2012-01-12 15:49:36