1. 程式人生 > >iOS開發-檢測使用者截圖, 並獲取所截圖片

iOS開發-檢測使用者截圖, 並獲取所截圖片

微信可以檢測到使用者截圖行為(Home + Power),並在稍後點選附加功能按鈕時詢問使用者是否要傳送剛才截圖的圖片,這個使用者體驗非常好。於是乎, 我也想著實現這個功能。

在iOS7之前, 如果使用者截圖,系統會自動取消螢幕上的所有 touch 事件,(使用 touchesCancelled:withEvent: 這個方法)那麼我們就可以檢測這個方法的呼叫,然後載入本地最新圖片再加以判斷來實現我們的目的。但在 iOS 7 之後,截圖不再會取消螢幕的 touch 事件,所以導致了 Snapchat 和 Facebook Poke 之類的應用在 iOS 7 剛釋出時依賴於系統這個行為的功能受到影響。

如果不採取任何新措施, 我們可以讓應用啟動後在後臺迴圈檢測相簿內最新一張照片,看它的是否符合截圖的特徵。這種方法可行,但這是個笨方法,需要使用者允許你的程式訪問相簿才可以,並且一直在後臺迴圈會消耗更多的系統資源。

當然, 蘋果封閉了一些東西, 肯定也會給你開放其他東西, 不會讓你走上絕路的。

iOS7提供一個嶄新的推送方法:UIApplicationUserDidTakeScreenshotNotification。只要像往常一樣訂閱即可知道什麼時候截圖了。
注意:UIApplicationUserDidTakeScreenshotNotification 將會在截圖完成之後顯示。現在在截圖擷取之前無法得到通知。

希望蘋果會在iOS8當中增加 UIApplicationUserWillTakeScreenshotNotification。(只有did, 沒有will顯然不是蘋果的風格...)

下面就寫了個小demo, 檢測使用者截圖, 並且獲取截圖照片, 顯示在右下角。

(需要在真機上執行, 至少, 模擬器上我不知道如何模擬截圖行為(Home + Power), 如果你知道, 還望告知)

一。註冊通知:

    //註冊通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(userDidTakeScreenshot:)
                                                 name:UIApplicationUserDidTakeScreenshotNotification object:nil];


二。監聽截圖:

執行操作, 也就是實現上面通知對應的響應函式  -- userDidTakeScreenshot

//截圖響應
- (void)userDidTakeScreenshot:(NSNotification *)notification
{
    NSLog(@"檢測到截圖");
    
    //人為截圖, 模擬使用者截圖行為, 獲取所截圖片
    UIImage *image_ = [self imageWithScreenshot];
    
    //新增顯示
    UIImageView *imgvPhoto = [[UIImageView alloc]initWithImage:image_];
    imgvPhoto.frame = CGRectMake(self.window.frame.size.width/2, self.window.frame.size.height/2, self.window.frame.size.width/2, self.window.frame.size.height/2);
    
    //新增邊框
    CALayer * layer = [imgvPhoto layer];
    layer.borderColor = [
                         [UIColor whiteColor] CGColor];
    layer.borderWidth = 5.0f;
    //新增四個邊陰影
    imgvPhoto.layer.shadowColor = [UIColor blackColor].CGColor;
    imgvPhoto.layer.shadowOffset = CGSizeMake(0, 0);
    imgvPhoto.layer.shadowOpacity = 0.5;
    imgvPhoto.layer.shadowRadius = 10.0;
    //新增兩個邊陰影
    imgvPhoto.layer.shadowColor = [UIColor blackColor].CGColor;
    imgvPhoto.layer.shadowOffset = CGSizeMake(4, 4);
    imgvPhoto.layer.shadowOpacity = 0.5;
    imgvPhoto.layer.shadowRadius = 2.0;

    [self.window addSubview:imgvPhoto];
}


我這裡的 userDidTakeScreenshot 總共做了3件事

1.列印檢測到截圖

2.獲取截圖圖片。呼叫[self imageWithScreenshot]; 這裡的imageWithScreenshot是人為截圖, 模擬使用者截圖操作, 獲取截圖圖片。

3.顯示截圖圖片, 以螢幕1/4大小顯示在右下角, 並且加上白色邊框和陰影效果突出顯示。

三。獲取截圖圖片

/**
 *  擷取當前螢幕
 *
 *  @return NSData *
 */
- (NSData *)dataWithScreenshotInPNGFormat
{
    CGSize imageSize = CGSizeZero;
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (UIInterfaceOrientationIsPortrait(orientation))
        imageSize = [UIScreen mainScreen].bounds.size;
    else
        imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
    
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    for (UIWindow *window in [[UIApplication sharedApplication] windows])
    {
        CGContextSaveGState(context);
        CGContextTranslateCTM(context, window.center.x, window.center.y);
        CGContextConcatCTM(context, window.transform);
        CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
        if (orientation == UIInterfaceOrientationLandscapeLeft)
        {
            CGContextRotateCTM(context, M_PI_2);
            CGContextTranslateCTM(context, 0, -imageSize.width);
        }
        else if (orientation == UIInterfaceOrientationLandscapeRight)
        {
            CGContextRotateCTM(context, -M_PI_2);
            CGContextTranslateCTM(context, -imageSize.height, 0);
        } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
            CGContextRotateCTM(context, M_PI);
            CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
        }
        if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])
        {
            [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
        }
        else
        {
            [window.layer renderInContext:context];
        }
        CGContextRestoreGState(context);
    }
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return UIImagePNGRepresentation(image);
}

/**
 *  返回擷取到的圖片
 *
 *  @return UIImage *
 */
- (UIImage *)imageWithScreenshot
{
    NSData *imageData = [self dataWithScreenshotInPNGFormat];
    return [UIImage imageWithData:imageData];
}


相關推薦

iOS開發-檢測使用者, 獲取圖片

微信可以檢測到使用者截圖行為(Home + Power),並在稍後點選附加功能按鈕時詢問使用者是否要傳送剛才截圖的圖片,這個使用者體驗非常好。於是乎, 我也想著實現這個功能。在iOS7之前, 如果使用者截圖,系統會自動取消螢幕上的所有 touch 事件,(使用 touches

iOS開發之視頻根據url獲取第一幀圖片,獲取任一幀圖片

keyword rac onerror 根據 ati parameter all ger mage + (UIImage*) thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time { AV

通過頁面自動獲取驗證碼圖片

比較慢,必須要有驗證碼才能生效,否則報錯,測試的時候自己手動點出驗證碼吧。。 這個是參考了某個部落格的,但是地址我忘了,就這樣吧。。 from selenium import webdriver from selenium.webdriver.support.ui import WebDriverW

android視訊播放製作成gif圖片

    導言:    根據文章標題,按三步走,一、視訊播放;二、連續截圖;三、轉換成gif。視訊播放很自然想到用MediaPlayer或者VideoView,但我在這裡踩了幾個坑,寫在這裡也希望別人少走點彎路。首先,是MediaPlayer+SurfaceView的坑,如果只

iOS開發——監聽系統獲得(含狀態列statusBar和鍵盤keyboard)

補充:經過真機測試,這份程式碼一點用都沒有-_- 專案需要得到獲得截圖然後生成自己的分享圖,某度能找到的基本都是怎麼獲取View的檢視,但是幾乎沒有提到包含狀態列(貌似只看到一個),而包含鍵盤的就真的沒有了。經過一翻查詢,在stackoverflow上找到了截

Unity iOS儲存到手機相簿總結

unity截圖方法 using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.UI; public class Screenshots : MonoBehaviour {

android 獲取螢幕呼叫系統分享

呼叫的系統自帶的分享而不是接入的第三方sdk 第一步: 獲取螢幕截圖 // 獲取螢幕(包括導航 View dView =AddressDetailsActivity.this.getWindow().getDecorView(); dVi

cropper.js 二次開發下載圖片

cropper.js 是一個基於jquery的圖片擷取庫。 參考:https://blog.csdn.net/weixin_38023551/article/details/78792400  我的程式碼也是基於這個同學的demo。 全程程式碼很長,所以我只貼出我改了的部分。  

Windows客戶端開發--儲存為JPG檔案

JPG和PNG的區別: PNG is a true color lossless format. In practice it can accomplish a compression on standard photos of a factor of 2-3

7、實現指令碼執行失敗 時自動儲存出錯資訊到檔案中

自動化指令碼如果失敗了,憑藉什麼去快速定位呢?當然是截圖和出錯資訊了,這裡就來實現這兩個功能。 方法是重寫TestListenerAdapter中的onTestFailure和onTestSkipped方法,在方法中新增截圖和儲存出錯資訊到文字的方法。 新建一個webtestListener.j

檔案上傳至oss後,獲取圖片縮率獲取視訊幀等後續操作

上一篇文章說了一下檔案上傳至oss:https://blog.csdn.net/new_programmer_h/article/details/84307005 這裡說一下上傳後的一些後續操作:常用的獲取圖片縮率圖、獲取視訊截幀生成封面圖。自我感覺阿里oss對於這些處理封裝的很好,只要根據:"%s|sys

python3 + opencv +pyzbar 攝像頭檢測二維碼獲取二維碼內容

程式碼直接複製執行即可,需要先安裝opencv和pyzbar的包 # coding:utf8 import cv2 import pyzbar.pyzbar as pyzbar def decodeDisplay(image): barcodes = pyzba

win32rgb24轉yuv420

void ScreenCap(void* buf, int w, int h) { HWND hDesk = GetDesktopWindow(); HDC hScreen = GetDC(hDesk); int width = w;//Get

在 Linux 下編輯的最佳工具

有幾種獲取螢幕截圖並對其進行新增文字、箭頭等編輯的方法,這裡提及的的螢幕截圖工具在 Ubuntu 和其它主流 Linux 發行版中都能夠使用。 當我的主力作業系統從 Windows 轉換到 Ubuntu 的時候,首要考慮的就是螢幕截圖工具的可用性。儘管使用預設的鍵

使用html2canvas.js實現頁面顯示或上傳

  最近寫專案有用到html2canvas.js,可以實現頁面的截圖功能,但遭遇了許多的坑,特此寫一篇隨筆記錄一下。   在使用html2canvas時可能會遇到諸如只能擷取視覺化介面、截圖沒有背景色、svg標籤無法擷取等問題,下面詳細的說明一下。 一、匯入html2canvas.js   這個不需要多

iOS開發中UIImageView逆時針旋轉,得到旋轉後的圖片

很多小夥伴會用系統的動畫旋轉,但都是順時針的,但是開發中有些場景需要用到逆時針旋轉效果更好,比方說tableView的 展開/收起 指示箭頭方向的變換,如果是順時針復位,就會顯得特別彆扭。以下一段程式碼可以解決問題: 此處的玄機在於: 1.系統認定的旋轉都是以原始位置為起點,如果想用

Python 複製到剪貼簿

除了開啟比較慢,要到資料夾中開啟,這些不太方便外,還是挺好用的。 import time import PyQt5 from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * cl

如何使用html5 canvas畫布對本地視訊進行上傳至伺服器

前端程式碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

iOS開發:自定義framework打包

文/CveniEs(簡書作者) 原文連結:http://www.jianshu.com/p/305b716df620 著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。 關於打包製作屬於自己的framework  首先宣告一下,我是一個菜鳥,只是在工作

Android實現View儲存到相簿

Android實現View截圖並儲存到相簿 一、目標 1. 效果圖 2. 下載地址 二、需求設計 三、準備工作 1. 實現View截圖 2. 儲存Bitmap到檔案