ios how to capture a particular portion of screen

后端 未结 6 1893
一生所求
一生所求 2020-12-14 11:41

I want to capture a particular portion of iPhone screen. I used UIGraphicsBeginImageContextWithOptions, but couldn\'t capture a portion of screen with this. Ple

相关标签:
6条回答
  • 2020-12-14 12:16

    you can use this code

    UIGraphicsBeginImageContext(self.view.bounds.size);
    
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    CGRect rect = CGRectMake(250,61 ,410, 255);
    CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
    
    UIImage *img = [UIImage imageWithCGImage:imageRef]; 
    
    UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil); 
    
    CGImageRelease(imageRef);
    
    0 讨论(0)
  • 2020-12-14 12:30

    Another method to capture clear screenshot;

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
                UIGraphicsBeginImageContextWithOptions(self.captureView.frame.size, NO, [UIScreen mainScreen].scale);
            else
                UIGraphicsBeginImageContext(self.captureView.frame.size);
    
            [self.captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
            UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
            [viewImage drawInRect:CGRectMake(0.0, 0.0, 640,960)];
            //NSData*m_Imgdata=UIImagePNGRepresentation(viewImage);
            NSData*m_Imgdata=UIImageJPEGRepresentation(viewImage, 1.0);
    
           // UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
    
            UIGraphicsEndImageContext();
    
    0 讨论(0)
  • 2020-12-14 12:32

    SWIFT 3.0 Xcode8 Version come from @jDutton answer and work for me.

    extension UIView {
        func imageSnapshot() -> UIImage {
            return self.imageSnapshotCroppedToFrame(frame: nil)
        }
    
        func imageSnapshotCroppedToFrame(frame: CGRect?) -> UIImage {
            let scaleFactor = UIScreen.main.scale
            UIGraphicsBeginImageContextWithOptions(bounds.size, false, scaleFactor)
            self.drawHierarchy(in: bounds, afterScreenUpdates: true)
            var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
    
            if let frame = frame {
                // UIImages are measured in points, but CGImages are measured in pixels
                let scaledRect = frame.applying(CGAffineTransform(scaleX: scaleFactor, y: scaleFactor))
    
                if let imageRef = image.cgImage!.cropping(to: scaledRect) {
                    image = UIImage(cgImage: imageRef)
                }
            }
            return image
        }
    }
    

    if you crash and get the following message:

    GContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
    CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
    

    try this solution

    Hope for saving your time!

    0 讨论(0)
  • 2020-12-14 12:33

    Here's a swift extension on UIView that will either capture the entire view or a frame within the view. It takes into account the screen scale.

    extension UIView {
    
        func imageSnapshot() -> UIImage {
            return self.imageSnapshotCroppedToFrame(nil)
        }
    
        func imageSnapshotCroppedToFrame(frame: CGRect?) -> UIImage {
            let scaleFactor = UIScreen.mainScreen().scale
            UIGraphicsBeginImageContextWithOptions(bounds.size, false, scaleFactor)
            self.drawViewHierarchyInRect(bounds, afterScreenUpdates: true)
            var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            if let frame = frame {
                // UIImages are measured in points, but CGImages are measured in pixels
                let scaledRect = CGRectApplyAffineTransform(frame, CGAffineTransformMakeScale(scaleFactor, scaleFactor))
    
                if let imageRef = CGImageCreateWithImageInRect(image.CGImage, scaledRect) {
                    image = UIImage(CGImage: imageRef)
                }
            }
            return image
        }
    }
    
    0 讨论(0)
  • 2020-12-14 12:39

    the answer by @Superdev is right on spot , what i want to add is a little trick if you want to capture a parent view and avoid subviews ( in particular overlay view ) what you can do is make this subview a property and use the following

    CGFloat width = CGRectGetWidth(self.view.bounds);
    CGFloat height = CGRectGetHeight(self.view.bounds);
    _overlayView.hidden = YES;
    UIGraphicsBeginImageContext(self.view.bounds.size);
    
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    CGRect rect = CGRectMake(0,0 ,width, height);
    CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
    
    UIImage *img = [UIImage imageWithCGImage:imageRef];
    
    UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
    
    CGImageRelease(imageRef);
    
    _overlayView.hidden = NO;
    

    its a small trick , hope someone will find it useful

    0 讨论(0)
  • 2020-12-14 12:41

    You can take screen shot using UIGraphicsGetImageFromCurrentContext. Wrote below code from memory, so errors possible. Please correct it yourself.

    - (UIImage*)captureView:(UIView *)yourView {
        CGRect rect = [[UIScreen mainScreen] bounds];
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
        [yourView.layer renderInContext:context];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
    
    0 讨论(0)
提交回复
热议问题