I am wondering how my iPhone app can take a screen shot of a specific UIView
as a UIImage
.
我想知道我的iPhone应用程序如何将一个特定的UIView作为一个UIImage的屏幕快照。
I tried this code but all I get is a blank image.
我尝试了这个代码,但是我得到的只是一个空白的图像。
UIGraphicsBeginImageContext(CGSizeMake(320,480));
CGContextRef context = UIGraphicsGetCurrentContext();
[myUIView.layer drawInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
myUIView
has dimensions 320x480 an it has some sub-views. What is the correct way to do this?
myUIView有320x480尺寸它有一些子视图。正确的做法是什么?
14 个解决方案
#1
69
I think you may want renderInContext
, not drawInContext
. drawInContext is more a method you would override...
我想你可能想要renderInContext,而不是drawInContext。drawInContext更像是一个你可以重写的方法。
Note that it may not work in all views, specifically a year or so ago when I tried to use this with the live camera view it did not work.
请注意,它可能不能在所有视图中工作,特别是在大约一年前,当我尝试将它与实时相机视图一起使用时,它不能工作。
#2
171
iOS 7 has a new method that allows you to draw a view hierarchy into the current graphics context. This can be used to get an UIImage very fast.
ios7有一个新方法,可以在当前图形上下文中绘制视图层次结构。这可以用来快速获取UIImage。
I implemented a category method on UIView
to get the view as an UIImage
:
我在UIView上实现了一个category方法将view作为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;
}
It is considerably faster then the existing renderInContext:
method.
它比现有的renderInContext:方法快得多。
Reference: https://developer.apple.com/library/content/qa/qa1817/_index.html
参考:https://developer.apple.com/library/content/qa/qa1817/_index.html
UPDATE FOR SWIFT: An extension that does the same:
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
}
}
UPDATE FOR SWIFT 3
更新快3
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)
drawHierarchy(in: self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
#3
61
You need to capture the key window for a screenshot or a UIView. You can do it in Retina Resolution using UIGraphicsBeginImageContextWithOptions and set its scale parameter 0.0f. It always captures in native resolution (retina for iPhone 4 and later).
您需要捕获屏幕快照或UIView的键窗口。你可以在视网膜分辨率使用UIGraphicsBeginImageContextWithOptions并设置它的比例参数0.0f。它总是以本地分辨率(iPhone 4和之后的视网膜)捕获。
This one does a full screen screenshot (key window)
这个是全屏截图(关键窗口)
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();
This code capture a UIView in native resolution
此代码以本机分辨率捕获UIView
CGRect rect = [captureView bounds];
UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[captureView.layer renderInContext:context];
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
This saves the UIImage in jpg format with 95% quality in the app's document folder if you need to do that.
如果你需要这样做的话,这可以节省jpg格式的UIImage,在应用程序的文档文件夹中有95%的质量。
NSString *imagePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/capturedImage.jpg"]];
[UIImageJPEGRepresentation(capturedImage, 0.95) writeToFile:imagePath atomically:YES];
#4
20
iOS7 onwards, we have below default methods :
iOS7向前,我们有以下默认的方法:
- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates
Calling above method is faster than trying to render the contents of the current view into a bitmap image yourself.
调用上述方法比自己将当前视图的内容呈现为位图映像要快。
If you want to apply a graphical effect, such as blur, to a snapshot, use the drawViewHierarchyInRect:afterScreenUpdates:
method instead.
如果您想对快照应用图形效果,比如blur,请使用drawViewHierarchyInRect:afterScreenUpdates: method。
https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html
#5
10
I have created usable extension for UIView to take screenshot in Swift:
我已经为UIView创建了可用的扩展,可以在Swift中截图:
extension UIView{
var screenshot: UIImage{
UIGraphicsBeginImageContext(self.bounds.size);
let context = UIGraphicsGetCurrentContext();
self.layer.renderInContext(context)
let screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenShot
}
}
To use it just type:
使用它只是类型:
let screenshot = view.screenshot
#6
6
- (void)drawRect:(CGRect)rect {
UIGraphicsBeginImageContext(self.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
}
This method may put in your Controller class.
这个方法可以放在您的Controller类中。
#7
4
CGImageRef UIGetScreenImage();
Apple now allows us to use it in a public application, even though it's a private API
苹果现在允许我们在公共应用程序中使用它,即使它是一个私有的API
#8
4
Apple does not allow:
苹果不允许:
CGImageRef UIGetScreenImage();
CGImageRef UIGetScreenImage();
Applications should take a screenshot using the drawRect
method as specified in: http://developer.apple.com/library/ios/#qa/qa2010/qa1703.html
应用程序应该使用drawRect方法进行截屏,如以下所示:http://developer.apple.com/library/ios/#qa/qa2010/qa1703.html
#9
4
I created this extension for save a screen shot from UIView
我创建了这个扩展,用于从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)
}}
call:
电话:
let pathDocuments = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).first!
let pathImage = "\(pathDocuments)/\(user!.usuarioID.integerValue).jpg"
reportView.saveImageFromView(path: pathImage)
If you want to create a png must change:
如果你想创建一个png,必须改变:
UIImageJPEGRepresentation(image, 0.4)?.writeToFile(path, atomically: true)
by
通过
UIImagePNGRepresentation(image)?.writeToFile(path, atomically: true)
#10
2
The following snippet is used to take screenshot :
以下片段用于截图:
UIGraphicsBeginImageContext(self.muUIView.bounds.size);
[myUIView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Use renderInContext:
method instead of drawInContext:
method
使用renderInContext:方法而不是drawInContext:方法
renderInContext:
method renders the receiver and its sublayers into current context. This method renders directly from the layer tree.
renderInContext:方法将接收者及其子类呈现到当前上下文中。此方法直接从层树中呈现。
#11
2
Details
xCode 8.2.1, Swift 3
xCode 8.2.1中,斯威夫特3
UIView Screen Shot in Swift
import UIKit
extension UIView {
var screenShot: UIImage? {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 1.0);
if let _ = UIGraphicsGetCurrentContext() {
drawHierarchy(in: bounds, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return screenshot
}
return nil
}
}
Usage
screenShotRenderer.image = viewForScreenShot.screenShot
Сomplete example of the use
View controller with UIView extension
带有UIView扩展名的视图控制器
import UIKit
class ViewController: UIViewController {
@IBOutlet var viewForScreenShot: UIView!
@IBOutlet var screenShotRenderer: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
@IBAction func makeViewScreenShotButtonTapped2(_ sender: UIButton) {
screenShotRenderer.image = viewForScreenShot.screenShot
}
}
extension UIView {
var screenShot: UIImage? {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 1.0);
if let _ = UIGraphicsGetCurrentContext() {
drawHierarchy(in: bounds, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return screenshot
}
return nil
}
}
Main.storyboard
Main.storyboard
<?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="*_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>
Result
#12
1
-(UIImage *)convertViewToImage
{
UIGraphicsBeginImageContext(self.bounds.size);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
#13
1
There is new API from iOS 10
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)
}
}
}
#14
0
you can use following UIView category -
你可以使用以下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
#1
69
I think you may want renderInContext
, not drawInContext
. drawInContext is more a method you would override...
我想你可能想要renderInContext,而不是drawInContext。drawInContext更像是一个你可以重写的方法。
Note that it may not work in all views, specifically a year or so ago when I tried to use this with the live camera view it did not work.
请注意,它可能不能在所有视图中工作,特别是在大约一年前,当我尝试将它与实时相机视图一起使用时,它不能工作。
#2
171
iOS 7 has a new method that allows you to draw a view hierarchy into the current graphics context. This can be used to get an UIImage very fast.
ios7有一个新方法,可以在当前图形上下文中绘制视图层次结构。这可以用来快速获取UIImage。
I implemented a category method on UIView
to get the view as an UIImage
:
我在UIView上实现了一个category方法将view作为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;
}
It is considerably faster then the existing renderInContext:
method.
它比现有的renderInContext:方法快得多。
Reference: https://developer.apple.com/library/content/qa/qa1817/_index.html
参考:https://developer.apple.com/library/content/qa/qa1817/_index.html
UPDATE FOR SWIFT: An extension that does the same:
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
}
}
UPDATE FOR SWIFT 3
更新快3
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)
drawHierarchy(in: self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
#3
61
You need to capture the key window for a screenshot or a UIView. You can do it in Retina Resolution using UIGraphicsBeginImageContextWithOptions and set its scale parameter 0.0f. It always captures in native resolution (retina for iPhone 4 and later).
您需要捕获屏幕快照或UIView的键窗口。你可以在视网膜分辨率使用UIGraphicsBeginImageContextWithOptions并设置它的比例参数0.0f。它总是以本地分辨率(iPhone 4和之后的视网膜)捕获。
This one does a full screen screenshot (key window)
这个是全屏截图(关键窗口)
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();
This code capture a UIView in native resolution
此代码以本机分辨率捕获UIView
CGRect rect = [captureView bounds];
UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[captureView.layer renderInContext:context];
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
This saves the UIImage in jpg format with 95% quality in the app's document folder if you need to do that.
如果你需要这样做的话,这可以节省jpg格式的UIImage,在应用程序的文档文件夹中有95%的质量。
NSString *imagePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/capturedImage.jpg"]];
[UIImageJPEGRepresentation(capturedImage, 0.95) writeToFile:imagePath atomically:YES];
#4
20
iOS7 onwards, we have below default methods :
iOS7向前,我们有以下默认的方法:
- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates
Calling above method is faster than trying to render the contents of the current view into a bitmap image yourself.
调用上述方法比自己将当前视图的内容呈现为位图映像要快。
If you want to apply a graphical effect, such as blur, to a snapshot, use the drawViewHierarchyInRect:afterScreenUpdates:
method instead.
如果您想对快照应用图形效果,比如blur,请使用drawViewHierarchyInRect:afterScreenUpdates: method。
https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html
#5
10
I have created usable extension for UIView to take screenshot in Swift:
我已经为UIView创建了可用的扩展,可以在Swift中截图:
extension UIView{
var screenshot: UIImage{
UIGraphicsBeginImageContext(self.bounds.size);
let context = UIGraphicsGetCurrentContext();
self.layer.renderInContext(context)
let screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenShot
}
}
To use it just type:
使用它只是类型:
let screenshot = view.screenshot
#6
6
- (void)drawRect:(CGRect)rect {
UIGraphicsBeginImageContext(self.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
}
This method may put in your Controller class.
这个方法可以放在您的Controller类中。
#7
4
CGImageRef UIGetScreenImage();
Apple now allows us to use it in a public application, even though it's a private API
苹果现在允许我们在公共应用程序中使用它,即使它是一个私有的API
#8
4
Apple does not allow:
苹果不允许:
CGImageRef UIGetScreenImage();
CGImageRef UIGetScreenImage();
Applications should take a screenshot using the drawRect
method as specified in: http://developer.apple.com/library/ios/#qa/qa2010/qa1703.html
应用程序应该使用drawRect方法进行截屏,如以下所示:http://developer.apple.com/library/ios/#qa/qa2010/qa1703.html
#9
4
I created this extension for save a screen shot from UIView
我创建了这个扩展,用于从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)
}}
call:
电话:
let pathDocuments = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).first!
let pathImage = "\(pathDocuments)/\(user!.usuarioID.integerValue).jpg"
reportView.saveImageFromView(path: pathImage)
If you want to create a png must change:
如果你想创建一个png,必须改变:
UIImageJPEGRepresentation(image, 0.4)?.writeToFile(path, atomically: true)
by
通过
UIImagePNGRepresentation(image)?.writeToFile(path, atomically: true)
#10
2
The following snippet is used to take screenshot :
以下片段用于截图:
UIGraphicsBeginImageContext(self.muUIView.bounds.size);
[myUIView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Use renderInContext:
method instead of drawInContext:
method
使用renderInContext:方法而不是drawInContext:方法
renderInContext:
method renders the receiver and its sublayers into current context. This method renders directly from the layer tree.
renderInContext:方法将接收者及其子类呈现到当前上下文中。此方法直接从层树中呈现。
#11
2
Details
xCode 8.2.1, Swift 3
xCode 8.2.1中,斯威夫特3
UIView Screen Shot in Swift
import UIKit
extension UIView {
var screenShot: UIImage? {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 1.0);
if let _ = UIGraphicsGetCurrentContext() {
drawHierarchy(in: bounds, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return screenshot
}
return nil
}
}
Usage
screenShotRenderer.image = viewForScreenShot.screenShot
Сomplete example of the use
View controller with UIView extension
带有UIView扩展名的视图控制器
import UIKit
class ViewController: UIViewController {
@IBOutlet var viewForScreenShot: UIView!
@IBOutlet var screenShotRenderer: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
@IBAction func makeViewScreenShotButtonTapped2(_ sender: UIButton) {
screenShotRenderer.image = viewForScreenShot.screenShot
}
}
extension UIView {
var screenShot: UIImage? {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 1.0);
if let _ = UIGraphicsGetCurrentContext() {
drawHierarchy(in: bounds, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return screenshot
}
return nil
}
}
Main.storyboard
Main.storyboard
<?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="*_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>
Result
#12
1
-(UIImage *)convertViewToImage
{
UIGraphicsBeginImageContext(self.bounds.size);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
#13
1
There is new API from iOS 10
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)
}
}
}
#14
0
you can use following UIView category -
你可以使用以下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