我的iPad应用程序有一个导航,我在其中显示不同页面的屏幕截图,因为我想一次显示多个屏幕截图,我将容器缩放到原始屏幕截图的大约24%(1024x768)。
- (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%并且清脆。
有没有办法在不破坏性能的情况下“平稳地”(动态地)缩放图像? 它有两个版本就足够了:全px和24%版本的另一个版本。
答案 0 :(得分:3)
缩小图像看起来很糟糕的原因是它在OpenGL中进行缩放,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 :(得分: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];