我使用一种方法从iOS应用程序中的各种视图中获取图像,以便让用户通过电子邮件发送屏幕。我绘制的大多数屏幕都工作正常,但是当我使用UIWebView的这种技术时,我只得到屏幕的可见部分。屏幕外的任何内容都不包含在渲染图像中。在Stack上一直在这里挖掘,但到目前为止我找不到任何作品?!
以下是我目前使用的方法:
-(NSData *)getImageFromView:(UIView *)view
{
NSData *pngImg;
CGFloat max, scale = 1.0;
CGSize size = [view bounds].size;
// Scale down larger images else we run into mem issues with mail widget
max = (size.width > size.height) ? size.width : size.height;
if( max > 960 )
scale = 960/max;
UIGraphicsBeginImageContextWithOptions( size, YES, scale );
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
pngImg = UIImagePNGRepresentation( UIGraphicsGetImageFromCurrentImageContext() );
UIGraphicsEndImageContext();
return pngImg;
}
答案 0 :(得分:5)
警告:不保证你不会遇到这个问题,我建议你在@autoreleasepool池中做这个,并考虑做一些扩展,就像我在示例中所做的那样,但是这个工作并且是我定居的:
-(NSData *)getImageFromView:(UIView *)view // Mine is UIWebView but should work for any
{
NSData *pngImg;
CGFloat max, scale = 1.0;
CGSize viewSize = [view bounds].size;
// Get the size of the the FULL Content, not just the bit that is visible
CGSize size = [view sizeThatFits:CGSizeZero];
// Scale down if on iPad to something more reasonable
max = (viewSize.width > viewSize.height) ? viewSize.width : viewSize.height;
if( max > 960 )
scale = 960/max;
UIGraphicsBeginImageContextWithOptions( size, YES, scale );
// Set the view to the FULL size of the content.
[view setFrame: CGRectMake(0, 0, size.width, size.height)];
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
pngImg = UIImagePNGRepresentation( UIGraphicsGetImageFromCurrentImageContext() );
UIGraphicsEndImageContext();
return pngImg; // Voila an image of the ENTIRE CONTENT, not just visible bit
}
答案 1 :(得分:1)
我刚刚为此创建了一个类别。当(并且仅当)Web视图缓存到内存中时,它才有效,否则页面的某些部分将显示为白色。
#import "UIWebView+Screenshot.h"
#import <QuartzCore/QuartzCore.h>
@implementation UIWebView (Screenshot)
- (UIImage *)screenshot {
UIImage *img = nil;
UIGraphicsBeginImageContextWithOptions(self.scrollView.contentSize, self.scrollView.opaque, 0.0);
{
CGPoint savedContentOffset = self.scrollView.contentOffset;
CGRect savedFrame = self.scrollView.frame;
self.scrollView.contentOffset = CGPointZero;
self.scrollView.frame = CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height);
[self.scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
img = UIGraphicsGetImageFromCurrentImageContext();
self.scrollView.contentOffset = savedContentOffset;
self.scrollView.frame = savedFrame;
}
UIGraphicsEndImageContext();
return img;
}
@end
答案 2 :(得分:0)
您可以缩小uiwebview以使所有内容都适合屏幕...但这仅在图像水平偏离屏幕时才有效。如果UIWebView比屏幕长,那么这不会做太多。
[webview.scrollView setZoomScale:webview.scrollView.minimumZoomScale animated:NO];
答案 3 :(得分:0)
WKWebView最近有一种更方便的方法
将此委托分配给webviews导航委托,并实现完成处理程序以获取图像
class WebviewDelegate: NSObject, WKNavigationDelegate {
var completion: ((UIImage?) -> ())?
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.body.offsetHeight;") { (result, error) in
if let height = result as? CGFloat {
let config = WKSnapshotConfiguration()
config.rect = CGRect(x: 0, y: 0, width: webView.scrollView.contentSize.width, height: height)
webView.takeSnapshot(with: config) { (image, error) in
self.completion?(image)
}
}
}
}
}