You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS截取屏幕2/3比例区域后全屏显示模糊,如何实现无损显示?

解决同比例2/3区域截图并全屏无损显示的问题

首先,你遇到的模糊问题核心原因是截图的像素密度不足——当你按点尺寸截取后,全屏拉伸时像素被放大,自然就会模糊。要实现无损显示,关键是保证截图的像素数和屏幕显示的像素数匹配,同时严格保持比例一致。下面分步骤给你解决方案:

一、先计算符合屏幕比例的2/3截取区域

首先得确保你截取的区域和主屏幕比例完全一致,这样全屏显示时不需要强制拉伸(拉伸是模糊的元凶之一)。假设你要截取的是高度为屏幕2/3的同比例区域(你可以根据需求调整为面积2/3的计算逻辑):

// 获取主屏幕的尺寸与比例
CGSize screenSize = UIScreen.main.bounds.size;
CGFloat screenRatio = screenSize.width / screenSize.height; // 竖屏比例,横屏的话反过来即可

// 计算目标区域:高度为屏幕的2/3,宽度按比例推导
CGFloat targetHeight = screenSize.height * 2.0 / 3.0;
CGFloat targetWidth = targetHeight * screenRatio;
// 让区域居中显示
CGFloat originX = (screenSize.width - targetWidth) / 2.0;
CGFloat originY = (screenSize.height - targetHeight) / 2.0;
CGRect captureRect = CGRectMake(originX, originY, targetWidth, targetHeight);

二、生成高清像素级截图

原来的代码可能没有明确指定屏幕的缩放因子(scale),导致截图的像素密度不够。修改你的getScreenshot方法,用屏幕原生scale来生成截图,保证像素数足够:

方式一:用传统的绘图上下文(兼容iOS 8+)

- (UIImage *)getScreenshot {
    // 第一步:计算符合比例的截取区域
    CGSize screenSize = UIScreen.main.bounds.size;
    CGFloat screenRatio = screenSize.width / screenSize.height;
    CGFloat targetHeight = screenSize.height * 2.0 / 3.0;
    CGFloat targetWidth = targetHeight * screenRatio;
    CGFloat originX = (screenSize.width - targetWidth) / 2.0;
    CGFloat originY = (screenSize.height - targetHeight) / 2.0;
    CGRect captureRect = CGRectMake(originX, originY, targetWidth, targetHeight);

    // 关键:用屏幕的scale创建上下文,保证截图是像素级高清的
    CGFloat screenScale = UIScreen.main.scale;
    UIGraphicsBeginImageContextWithOptions(captureRect.size, YES, screenScale);
    CGContextRef context = UIGraphicsGetCurrentContext();

    // 转换坐标(CoreGraphics坐标原点在左下角,UIKit在左上角,需要翻转对齐)
    CGContextTranslateCTM(context, -captureRect.origin.x, -captureRect.origin.y);
    // 渲染整个屏幕的layer到上下文(如果是截取_shareView的话,替换成[_shareView.layer renderInContext:context])
    [self.view.layer renderInContext:context];

    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return screenshot;
}

方式二:用UIGraphicsImageRenderer(iOS 10+,更简洁)

- (UIImage *)getScreenshot {
    CGSize screenSize = UIScreen.main.bounds.size;
    CGFloat screenRatio = screenSize.width / screenSize.height;
    CGFloat targetHeight = screenSize.height * 2.0 / 3.0;
    CGFloat targetWidth = targetHeight * screenRatio;
    CGFloat originX = (screenSize.width - targetWidth) / 2.0;
    CGFloat originY = (screenSize.height - targetHeight) / 2.0;
    CGRect captureRect = CGRectMake(originX, originY, targetWidth, targetHeight);

    // 直接指定scale为屏幕原生scale
    UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:captureRect.size scale:UIScreen.main.scale];
    UIImage *screenshot = [renderer imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
        CGContextRef context = rendererContext.CGContext;
        CGContextTranslateCTM(context, -captureRect.origin.x, -captureRect.origin.y);
        [self.view.layer renderInContext:context];
    }];

    return screenshot;
}

三、全屏显示时的正确姿势

拿到高清截图后,全屏显示时要避免强制拉伸,用正确的contentMode来适配:

// 创建全屏ImageView
UIImageView *fullScreenImageView = [[UIImageView alloc] initWithFrame:UIScreen.main.bounds];
fullScreenImageView.image = [self getScreenshot];
// 选择合适的适配模式:ScaleAspectFill会填满屏幕(裁剪多余部分),ScaleAspectFit会完整显示(留边)
fullScreenImageView.contentMode = UIViewContentModeScaleAspectFill;
fullScreenImageView.clipsToBounds = YES; // 用ScaleAspectFill时需要开启裁剪
// 关键:设置contentScaleFactor为屏幕scale,保证系统用高清像素渲染
fullScreenImageView.contentScaleFactor = UIScreen.main.scale;

[self.view addSubview:fullScreenImageView];

为什么原来的代码会模糊?

原来的代码中,你用了_shareView.bounds.size作为上下文尺寸,并且scale传了0.0——虽然0.0会取当前上下文的scale,但如果_shareView的尺寸不是按屏幕比例设计的,或者截图的像素数远小于屏幕的像素数,当全屏拉伸时,像素被强制放大,就会出现模糊。现在我们通过明确使用屏幕scale生成截图,保证截图的像素密度和屏幕完全一致,再配合正确的显示模式,就能实现无损全屏显示了。

内容的提问来源于stack exchange,提问作者birdcage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:35:24