如何在IOS设备上拍摄清晰的屏幕截图

6

我正在开发一个iOS应用程序,需要进行清晰屏幕截图。我尝试过

func captureView() -> UIImage {
        //hide controls if needed
        let rect: CGRect = self.imageView.frame
        UIGraphicsBeginImageContext(rect.size)
        let context: CGContextRef = UIGraphicsGetCurrentContext()!
        self.view.layer.renderInContext(context)
        let img: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img
    }

但图像质量不好。请为我提供一些建议。

2
你尝试过这个吗:http://stackoverflow.com/questions/14797104/taking-screenshot-of-high-quality-ios? - Duyen-Hoa
5个回答

11

改变这行

UIGraphicsBeginImageContext(rect.size)

UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0);

亲爱的,你有没有想法在同一段代码中...我从imageView中没有得到适当的图像。 - JAck
1
很棒的解决方案,关键是将比例设置为0.0,这样截图就会保持完整的质量! - Mario Jaramillo

3

在一个新文件中添加以下代码块。就这样。

extension UIView {

    // Convert a uiview to uiimage
        func captureView() -> UIImage {
            // Gradually increase the number for high resolution.     
            let scale = 1.0 

            UIGraphicsBeginImageContextWithOptions(bounds.size, opaque, scale)   

            layer.renderInContext(UIGraphicsGetCurrentContext()!)
            let image:UIImage  = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return image
        }
    }

现在,您可以在任何UIView的子类和UIView本身上调用captureView()方法来获取视图的UIImage。
您可以更改UIGraphicsBeginImageContextWithOptions方法中scale的值以获得高分辨率图像。

2
您可以使用IOSurface私有框架来实现此操作。
IOMobileFramebufferConnection connect;
kern_return_t result;
IOSurfaceRef screenSurface = NULL;

io_service_t framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleH1CLCD"));
if(!framebufferService)
    framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleM2CLCD"));
if(!framebufferService)
    framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleCLCD"));

result = IOMobileFramebufferOpen(framebufferService, mach_task_self(), 0, &connect);

result = IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &screenSurface);

uint32_t aseed;
IOSurfaceLock(screenSurface, kIOSurfaceLockReadOnly, &aseed);
uint32_t width = IOSurfaceGetWidth(screenSurface);
uint32_t height = IOSurfaceGetHeight(screenSurface);

CFMutableDictionaryRef dict;
int pitch = width*4, size = width*height*4;
int bPE=4;
char pixelFormat[4] = {'A','R','G','B'};
dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(dict, kIOSurfaceIsGlobal, kCFBooleanTrue);
CFDictionarySetValue(dict, kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch));
CFDictionarySetValue(dict, kIOSurfaceBytesPerElement, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bPE));
CFDictionarySetValue(dict, kIOSurfaceWidth, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width));
CFDictionarySetValue(dict, kIOSurfaceHeight, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height));
CFDictionarySetValue(dict, kIOSurfacePixelFormat, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat));
CFDictionarySetValue(dict, kIOSurfaceAllocSize, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &size));

IOSurfaceRef destSurf = IOSurfaceCreate(dict);

void* outAcc;
IOSurfaceAcceleratorCreate(NULL, 0, &outAcc);

IOSurfaceAcceleratorTransferSurface(outAcc, screenSurface, destSurf, dict, NULL);

IOSurfaceUnlock(screenSurface, kIOSurfaceLockReadOnly, &aseed);
CFRelease(outAcc);

CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, IOSurfaceGetBaseAddress(destSurf), (width * height * 4), NULL);
CGImageRef cgImage=CGImageCreate(width, height, 8,
                                 8*4, IOSurfaceGetBytesPerRow(destSurf),
                                 CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst |kCGBitmapByteOrder32Little,
                                 provider, NULL,
                                 YES, kCGRenderingIntentDefault);
UIImage *img = [UIImage imageWithCGImage:cgImage];

0

使用

UIGraphicsBeginImageContextWithOptions(你的尺寸, 是否透明, 缩放比例)

代替

UIGraphicsBeginImageContext(rect.size)


0
在UIGraphicsBeginImageContextWithOptions中的最后一个参数是比例尺。如果您只需要高分辨率,请尝试将比例尺的值设置为1.0。
func captureView() -> UIImage {
        //hide controls if needed
        let rect: CGRect = self.imageView.frame

        UIGraphicsBeginImageContextWithOptions(rect.size, true, 1.0)//add this line

        let context: CGContextRef = UIGraphicsGetCurrentContext()!
        self.view.layer.renderInContext(context)
        let img: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接