How to clear iOS screen

I am working on an iOS application that requires a clear screenshot. I tried

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
    }

But the image quality is not very good. Please offer me something for this.

+4
source share
5 answers

change the line

UIGraphicsBeginImageContext(rect.size)

to

UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0);
+6
source

Add the following block of code to the new file. And you go there.

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
        }
    }

Now you can call captureView()for any subclass UIViewand UIView itself to get the UIImage of the view.

You can change the value scalein the method UIGraphicsBeginImageContextWithOptionsto get a high resolution image.

+3
source

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];
+1

UIGraphicsBeginImageContextWithOptions(your size, opaque, scale

UIGraphicsBeginImageContext(rect.size)

0

The last parameter in UIGraphicsBeginImageContextWithOptions is the scale. If you need only high resolution, try setting the scale value to 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
    }
0
source

Source: https://habr.com/ru/post/1649783/


All Articles