2011-10-27 10 views
7

Chcę przechwycić konkretną część ekranu iPhone'a. Użyłem UIGraphicsBeginImageContextWithOptions, ale nie udało mi się uchwycić części ekranu. Proszę, pomóż mi.ios jak uchwycić konkretną część ekranu

+0

chcesz zrobić zrzut ekranu z urządzenia lub chcesz przechwycić obszar w aplikacji za pomocą kodu? – mAc

+2

@mAc oczywiście chce to zrobić z kodem ... jeśli nie, to dlaczego używa UIGraphicsBeginImageContextWithOptions – Krishnabhadra

Odpowiedz

15

Możesz wykonać zrzut ekranu przy użyciu UIGraphicsGetImageFromCurrentContext. Napisany poniżej kod z pamięci, więc możliwe błędy. Popraw to sam.

- (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; 
} 
25

można użyć tego kodu

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); 
+3

, jest to przydatne, gdy musisz uchwycić określony obszar ekranu. – priyanka

+2

świetny kumpel :) –

+0

Mam szczególną część przez to. Ale w niektórych poglądach ukrywa swoją treść. Czy możesz dać pojęcie, dlaczego tak się dzieje? – Niharika

0

Inny sposób uchwycić wyraźny zrzut ekranu;

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(); 
1

odpowiedź przez @Superdev jest tuż na miejscu, co chcę dodać to mały trick, jeśli chcesz uchwycić widok rodzica i uniknąć subviews (w szczególności widzenia nakładki), co można zrobić, to zrobić to podrzędny obiekt i użyć następujących

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; 

jej mała sztuczka, nadzieję, że ktoś znajdzie to użyteczne

3

Oto szybka rozbudowa na UIView które albo przechwycić cały widok lub ramkę w widoku. Bierze pod uwagę skalę ekranu.

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

Witaj, jDutton. Kochałem twoją odpowiedź. Postanowiliśmy zaktualizować Twój kod do Swift 3.0. –

+0

Dziękuję bardzo! – Jerome

0

SWIFT 3,0 Xcode8 Wersja pochodzą z @jDutton odpowiedź i pracy dla mnie.

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

jeśli upaść i pojawia się następujący komunikat:

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. 

spróbować tej solution

Nadzieja na oszczędność czasu!