UIView 스크린샷을 찍는 방법
아이폰 앱이 어떻게 특정 스크린샷을 찍을 수 있는지 궁금합니다.UIView
로서UIImage
.
이 코드를 사용했지만 아무것도 표시되지 않습니다.
UIGraphicsBeginImageContext(CGSizeMake(320,480));
CGContextRef context = UIGraphicsGetCurrentContext();
[myUIView.layer drawInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
myUIView
치수가 320x420이고 서브패턴이 몇 가지 있습니다.올바른 방법은 무엇입니까?
iOS 7에는 뷰 계층을 현재 그래픽 컨텍스트에 그릴 수 있는 새로운 방법이 있습니다.이것은 매우 빠르게 UIIMage를 얻기 위해 사용할 수 있습니다.
다음 항목에 대한 범주 방법을 구현했습니다.UIView
시야를 넓히다UIImage
:
- (UIImage *)pb_takeSnapshot {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
// old style [self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
기존보다 상당히 빠릅니다.renderInContext:
방법.
참고 자료: https://developer.apple.com/library/content/qa/qa1817/_index.html
SWIFT 업데이트: 동일한 기능을 수행하는 확장:
extension UIView {
func pb_takeSnapshot() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.mainScreen().scale)
drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
// old style: layer.renderInContext(UIGraphicsGetCurrentContext())
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
SWIFT 3 업데이트
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)
drawHierarchy(in: self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
네가 원할 것 같아renderInContext
,것은 아니다.drawInContext
. drawInContext는 덮어쓰는 메서드에 가깝습니다.
특히 1년 전쯤 라이브 카메라 뷰에서 사용하려고 했을 때 모든 뷰에서 동작하는 것은 아닙니다.
스크린샷 또는 UIView의 키 창을 캡처해야 합니다.UIGraphicsBeginImageContextWithOptions를 사용하여 Retina Resolution에서 이를 수행하고 스케일 파라미터 0.0f를 설정할 수 있습니다.항상 네이티브 해상도로 캡처합니다(iPhone 4 이후의 경우 레티나).
이것은 전체 화면 스크린샷(키 창)을 수행합니다.
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage *capturedScreen = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
이 코드는 네이티브 해상도로 UIView를 캡처합니다.
CGRect rect = [captureView bounds];
UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[captureView.layer renderInContext:context];
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
이렇게 하면 UIImage가 95% 품질로 jpg 형식으로 앱 문서 폴더에 저장됩니다.
NSString *imagePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/capturedImage.jpg"]];
[UIImageJPEGRepresentation(capturedImage, 0.95) writeToFile:imagePath atomically:YES];
iOS7 이후에는 다음과 같은 기본 방식이 있습니다.
- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates
위의 메서드를 호출하는 것이 현재 보기의 내용을 직접 비트맵 이미지로 렌더링하는 것보다 빠릅니다.
스냅샷에 흐림 등의 그래픽 효과를 적용하려면drawViewHierarchyInRect:afterScreenUpdates:
대신 메서드를 사용합니다.
iOS 10의 새로운 API가 있습니다.
extension UIView {
func makeScreenshot() -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
return renderer.image { (context) in
self.layer.render(in: context.cgContext)
}
}
}
UIView가 Swift에서 스크린샷을 찍기 위해 사용할 수 있는 확장을 만들었습니다.
extension UIView{
var screenshot: UIImage{
UIGraphicsBeginImageContext(self.bounds.size);
let context = UIGraphicsGetCurrentContext();
self.layer.renderInContext(context)
let screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenShot
}
}
사용하려면 다음과 같이 입력합니다.
let screenshot = view.screenshot
- (void)drawRect:(CGRect)rect {
UIGraphicsBeginImageContext(self.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
}
이 메서드는 컨트롤러 클래스에 넣을 수 있습니다.
세부 사항
- Xcode 버전 10.3 (10G8) Swift 5
솔루션
import UIKit
extension CALayer {
func makeSnapshot() -> UIImage? {
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)
defer { UIGraphicsEndImageContext() }
guard let context = UIGraphicsGetCurrentContext() else { return nil }
render(in: context)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
return screenshot
}
}
extension UIView {
func makeSnapshot() -> UIImage? {
if #available(iOS 10.0, *) {
let renderer = UIGraphicsImageRenderer(size: frame.size)
return renderer.image { _ in drawHierarchy(in: bounds, afterScreenUpdates: true) }
} else {
return layer.makeSnapshot()
}
}
}
사용.
let image = view.makeSnapshot()
풀샘플
여기에 솔루션 코드를 추가하는 것을 잊지 마십시오.
import UIKit
class ViewController: UIViewController {
@IBOutlet var viewForScreenShot: UIView!
@IBOutlet var screenShotRenderer: UIImageView!
@IBAction func makeViewScreenShotButtonTapped2(_ sender: UIButton) {
screenShotRenderer.image = viewForScreenShot.makeSnapshot()
}
}
Main. 스토리보드
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_2214957" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Acg-GO-mMN">
<rect key="frame" x="67" y="28" width="240" height="128"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="4Fr-O3-56t">
<rect key="frame" x="72" y="49" width="96" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="cLv-es-h7Q"/>
<constraint firstAttribute="width" constant="96" id="ytF-FH-gdm"/>
</constraints>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="0.49277611300000002" colorSpace="custom" customColorSpace="sRGB"/>
<color key="tintColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="4Fr-O3-56t" firstAttribute="centerX" secondItem="Acg-GO-mMN" secondAttribute="centerX" id="egj-rT-Gz5"/>
<constraint firstItem="4Fr-O3-56t" firstAttribute="centerY" secondItem="Acg-GO-mMN" secondAttribute="centerY" id="ymi-Ll-WIV"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SQq-IE-pvj">
<rect key="frame" x="109" y="214" width="157" height="30"/>
<state key="normal" title="make view screen shot"/>
<connections>
<action selector="makeViewScreenShotButtonTapped2:" destination="BYZ-38-t0r" eventType="touchUpInside" id="KSY-ec-uvA"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="CEZ-Ju-Tpq">
<rect key="frame" x="67" y="269" width="240" height="128"/>
<constraints>
<constraint firstAttribute="width" constant="240" id="STo-iJ-rM4"/>
<constraint firstAttribute="height" constant="128" id="tfi-zF-zdn"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" red="0.95941069162436543" green="0.95941069162436543" blue="0.95941069162436543" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="CEZ-Ju-Tpq" firstAttribute="top" secondItem="SQq-IE-pvj" secondAttribute="bottom" constant="25" id="6x1-iB-gKF"/>
<constraint firstItem="Acg-GO-mMN" firstAttribute="leading" secondItem="CEZ-Ju-Tpq" secondAttribute="leading" id="LUp-Be-FiC"/>
<constraint firstItem="SQq-IE-pvj" firstAttribute="top" secondItem="Acg-GO-mMN" secondAttribute="bottom" constant="58" id="Qu0-YT-k9O"/>
<constraint firstItem="Acg-GO-mMN" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="Qze-zd-ajY"/>
<constraint firstItem="Acg-GO-mMN" firstAttribute="trailing" secondItem="CEZ-Ju-Tpq" secondAttribute="trailing" id="b1d-sp-GHD"/>
<constraint firstItem="SQq-IE-pvj" firstAttribute="centerX" secondItem="CEZ-Ju-Tpq" secondAttribute="centerX" id="qCL-AF-Cro"/>
<constraint firstItem="Acg-GO-mMN" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="8" symbolic="YES" id="u5Y-eh-oSG"/>
<constraint firstItem="CEZ-Ju-Tpq" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="vkx-JQ-pOF"/>
</constraints>
</view>
<connections>
<outlet property="screenShotRenderer" destination="CEZ-Ju-Tpq" id="8QB-OE-ib6"/>
<outlet property="viewForScreenShot" destination="Acg-GO-mMN" id="jgL-yn-8kk"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="32.799999999999997" y="37.331334332833585"/>
</scene>
</scenes>
</document>
결과
CGImageRef UIGetScreenImage();
애플은 개인 API임에도 불구하고 공개 어플리케이션에서 사용할 수 있게 되었습니다.
Apple은 다음을 허용하지 않습니다.
CGImageRef UIGetScreenImage();
프로그램은 을 .drawRect
http://developer.apple.com/library/ios/ #qa/qa2010/qa1703.http://http://developer.apple.com/library/ios/ 에 지정된 메서드
UIView에서 찍은 스크린샷을 저장하기 위해 이 확장자를 만들었습니다.
extension UIView {
func saveImageFromView(path path:String) {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.mainScreen().scale)
drawViewHierarchyInRect(bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageJPEGRepresentation(image, 0.4)?.writeToFile(path, atomically: true)
}}
호출:
let pathDocuments = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).first!
let pathImage = "\(pathDocuments)/\(user!.usuarioID.integerValue).jpg"
reportView.saveImageFromView(path: pathImage)
png를 작성하려면 다음을 변경해야 합니다.
UIImageJPEGRepresentation(image, 0.4)?.writeToFile(path, atomically: true)
타고
UIImagePNGRepresentation(image)?.writeToFile(path, atomically: true)
Swift 4 갱신일 :
extension UIView {
var screenShot: UIImage? {
if #available(iOS 10, *) {
let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
return renderer.image { (context) in
self.layer.render(in: context.cgContext)
}
} else {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 5);
if let _ = UIGraphicsGetCurrentContext() {
drawHierarchy(in: bounds, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return screenshot
}
return nil
}
}
}
다음 스니펫을 사용하여 스크린샷을 촬영합니다.
UIGraphicsBeginImageContext(self.muUIView.bounds.size);
[myUIView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
renderInContext:
method를 합니다.drawInContext:
renderInContext:
method는 수신자와 그 서브레이어를 현재 컨텍스트에 렌더링합니다.이 메서드는 레이어 트리에서 직접 렌더링합니다.
-(UIImage *)convertViewToImage
{
UIGraphicsBeginImageContext(self.bounds.size);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
다음의 UIView 카테고리를 사용할 수 있습니다.
@implementation UIView (SnapShot)
- (UIImage *)snapshotImage
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO];
// old style [self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
@end
// MARK: - Actions
@objc func imageWasSaved(_ image: UIImage, error: Error?, context: UnsafeMutableRawPointer) {
if let error = error {
print(error.localizedDescription)
return
}
print("Image was saved in the photo gallery")
UIApplication.shared.open(URL(string:"photos-redirect://")!)
}
func takeScreenshot(of view: UIView) {
let bounds = UIScreen.main.bounds
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)
self.view.drawHierarchy(in: self.view.bounds, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, self, #selector(imageWasSaved), nil)
}
언급URL : https://stackoverflow.com/questions/2214957/how-do-i-take-a-screen-shot-of-a-uiview
'programing' 카테고리의 다른 글
WPF에서 AppBar 도킹(WinAmp와 같은 화면 가장자리)은 어떻게 합니까? (0) | 2023.04.15 |
---|---|
C#에서 키 누르기 이벤트를 프로그래밍 방식으로 생성하려면 어떻게 해야 합니까? (0) | 2023.04.15 |
Bash에서 문자열 변수를 연결하는 방법 (0) | 2023.04.15 |
bat 파일에서 여러 maven 명령을 실행하는 방법은 무엇입니까? (0) | 2023.04.15 |
셀에 문자열이 포함되어 있는 경우 (0) | 2023.04.15 |