截屏、圖片裁剪、拼接

我們在開發(fā)中經常需要使用截屏功能或者把某個view生成一張圖片的功能,還有可能需要拼接在一起組成一張大圖,另外有可能給一張大圖添加水印圖等。

屏幕截圖

屏幕截圖和view截成圖一樣,只是把對應的view換成window就行,示例代碼如下

    UIGraphicsBeginImageContextWithOptions([UIApplication sharedApplication].keyWindow.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIApplication sharedApplication].keyWindow .layer renderInContext:context];
    UIImage *image= UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

這樣截圖出來的圖片沒有頂部狀態(tài)欄,因為狀態(tài)欄并不在keyWindow對應的view上,所以我們要加上相應的UIStatueBar

    UIGraphicsBeginImageContextWithOptions([UIApplication sharedApplication].keyWindow.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIApplication sharedApplication].keyWindow .layer renderInContext:context];
    //添加頂部狀態(tài)欄
    UIView *statusBarView = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    [statusBarView.layer renderInContext:context];
    UIImage *image= UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

獲取頂部狀態(tài)欄View的方法OTScreenshotHelper中用的是runtime,也是可以獲取到,有興趣的同學可以去看下https://github.com/OpenFibers/OTScreenshotHelper
以上方法還有一個問題,就是對于有UIPickerView在頁面上,PickView會有黑邊,所以我們要把renderInContext替換成drawViewHierarchyInRect,示例代碼如下

    UIGraphicsBeginImageContextWithOptions([UIApplication sharedApplication].keyWindow.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIApplication sharedApplication].keyWindow drawViewHierarchyInRect:(CGRect){.origin=CGPointZero, .size=[UIApplication sharedApplication].keyWindow.bounds.size} afterScreenUpdates:YES];
    //添加頂部狀態(tài)欄
    UIView *statusBarView = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    [statusBarView.layer renderInContext:context];
    UIImage *image= UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

UIScrollView圖片裁剪

一般的view的生成圖片和上面截屏方法類似,而且可以不考慮頂部狀態(tài)欄。對于UIScrollView用上面的方法獲取的圖片也是我們可見的,如果我們想要獲取整個ContentSize的圖片,對于UITableView和UICollectionView往往會留下一片空白部分,達不到我們想要的效果。要達到整個都截取的話,我們可以分段截圖,然后拼接,也可以改變其frame,讓所有cell都渲染出來。

- (UIImage *)screenshotImageWithScrollView:(UIScrollView *)scrollView
                                imageSize:(CGSize)size{
    CGPoint orignalContentOffset = scrollView.contentOffset;
    CGRect orignalFrame = scrollView.frame;
    
    UIScrollView *rt = scrollView;
    CGRect frm = scrollView.frame;
    frm.size.height = size.height;
    rt.frame = frm;
    
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [rt.layer renderInContext:context];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    scrollView.contentOffset = orignalContentOffset;
    scrollView.frame = orignalFrame;
    return viewImage;
}

上面就是改變ScrollView的frame,高度和contentSize的height一樣,等截圖才做完成后重新回到它原狀態(tài)。裁剪ScrollView生成圖片的尺寸和我們給的尺寸有變差,需要注意生成圖片的scale,裁剪示例代碼如下

    UIImage *screenImg = [self screenshotImageWithScrollView:scrollView imageSize:scrollView.contentSize];
    CGImageRef screenImageRef = screenImg.CGImage;
    CGImageRef rectImageRef = CGImageCreateWithImageInRect(screenImageRef, CGRectMake(rect.origin.x*screenImg.scale, rect.origin.y*screenImg.scale, rect.size.width*screenImg.scale, rect.size.height*screenImg.scale));
    UIImage* rectImage = [UIImage imageWithCGImage:rectImageRef];
    CGImageRelease(rectImageRef);

圖片添加水印

圖片拼接、添加水印都基本一樣,都在畫布中畫出圖片

- (UIImage *)imageAddMaskWithImage:(UIImage *)orignalImage
                         imageSize:(CGSize)imageSize
                         maskImage:(UIImage *)maskImage
                     maskImageRect:(CGRect)maskRect
                         maskAlpha:(CGFloat)maskAlpha{
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
    [orignalImage drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
    [maskImage drawInRect:maskRect blendMode:kCGBlendModeNormal alpha:maskAlpha];
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultingImage;
}

總結

以上都是靜態(tài)頁面的截圖,對于正在執(zhí)行動畫的頁面沒測試,有興趣的同學可以嘗試一下。另外對于WebView上述方式是截取不了整個WebView,這有個解決方法http://www.itdecent.cn/p/ef50defb979d,最后附上demoOCSwift。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容