如何在自己的應用程序中進行長截屏?

不知道各位在開發過程中是否碰到過此類的需求,產品要求開發人員將長長的文章或者是瀏覽的內容進行截屏然后將截圖所獲得的圖片分享出去或者上傳到服務器。

筆者遇到了這樣一個需求,要求開發人員將配置好的商品發送出去的同時截圖上傳至服務器。然后以此作為一個記錄,便于日后方便取用。看了并簡單寫了一個測試demo試了一下。

// 長截圖 類型可以是 tableView或者scrollView 等可以滾動的視圖 根據需要自己改

- (void)saveLongImage:(UITableView *)table {

UIImage* image = nil;

// 下面方法,第一個參數表示區域大小。第二個參數表示是否是非透明的。如果需要顯示半透明效果,需要傳NO,否則傳YES。第三個參數就是屏幕密度了,調整清晰度。

UIGraphicsBeginImageContextWithOptions(table.contentSize, YES, [UIScreen mainScreen].scale);

CGPoint savedContentOffset = table.contentOffset;

CGRect savedFrame = table.frame;

table.contentOffset = CGPointZero;

table.frame = CGRectMake(0, 0, table.contentSize.width, table.contentSize.height);

[table.layer renderInContext: UIGraphicsGetCurrentContext()];

image = UIGraphicsGetImageFromCurrentImageContext();

table.contentOffset = savedContentOffset;

table.frame = savedFrame;

UIGraphicsEndImageContext();

if (image != nil) {

//保存圖片到相冊

UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);

}

}

重點是獲取所要截屏的長度和寬度大小。即使獲取屏幕上控件的高度加在一起。獲取將要裁剪的尺寸。那么如果截圖成功了。如何將圖片保存呢?

// 保存后回調方法

- (void)image: (UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {

NSString *msg = nil ;

if(error != NULL){

msg = @"保存圖片失敗" ;

}else{

msg = @"保存圖片成功,可到相冊查看" ;

}

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:@"確定" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];

UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];

[alertController addAction:cancelAction];

[alertController addAction:okAction];

[self presentViewController:alertController animated:YES completion:nil];

}

微信可以檢測到用戶截屏行為(Home + Power),并在稍后點擊附加功能按鈕時詢問用戶是否要發送剛才截屏的圖片,這個用戶體驗非常好。于是乎, 我也想著實現這個功能。

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

如果不采取任何新措施, 我們可以讓應用啟動后在后臺循環檢測相冊內最新一張照片,看它的是否符合截屏的特征。這種方法可行,但這是個笨方法,需要用戶允許你的程序訪問相冊才可以,并且一直在后臺循環會消耗更多的系統資源。

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

iOS7提供一個嶄新的推送方法:

UIApplicationUserDidTakeScreenshotNotification

。只要像往常一樣訂閱即可知道什么時候截圖了。

注意:UIApplicationUserDidTakeScreenshotNotification

將會在截圖完成之后顯示

。現在在截圖截取之前無法得到通知。

一。注冊通知:

//注冊通知[[NSNotificationCenter defaultCenter]addObserver:selfselector:@selector(userDidTakeScreenshot:)name:UIApplicationUserDidTakeScreenshotNotificationobject:nil];

二。監聽截屏:

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

//截屏響應- (void)userDidTakeScreenshot:(NSNotification*)notification{NSLog(@"檢測到截屏");//人為截屏, 模擬用戶截屏行為, 獲取所截圖片UIImage*image_ = [selfimageWithScreenshot];//添加顯示UIImageView*imgvPhoto = [[UIImageViewalloc]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 = [? ? [UIColorwhiteColor]CGColor];? ? layer.borderWidth =5.0f;//添加四個邊陰影imgvPhoto.layer.shadowColor = [UIColorblackColor].CGColor;? ? imgvPhoto.layer.shadowOffset =CGSizeMake(0,0);? ? imgvPhoto.layer.shadowOpacity =0.5;? ? imgvPhoto.layer.shadowRadius =10.0;//添加兩個邊陰影imgvPhoto.layer.shadowColor = [UIColorblackColor].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{CGSizeimageSize =CGSizeZero;UIInterfaceOrientationorientation = [UIApplicationsharedApplication].statusBarOrientation;if(UIInterfaceOrientationIsPortrait(orientation))imageSize = [UIScreenmainScreen].bounds.size;elseimageSize =CGSizeMake([UIScreenmainScreen].bounds.size.height, [UIScreenmainScreen].bounds.size.width);UIGraphicsBeginImageContextWithOptions(imageSize,NO,0);CGContextRefcontext =UIGraphicsGetCurrentContext();for(UIWindow*windowin[[UIApplicationsharedApplication] 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);}elseif(orientation ==UIInterfaceOrientationLandscapeRight){CGContextRotateCTM(context, -M_PI_2);CGContextTranslateCTM(context, -imageSize.height,0);}elseif(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();returnUIImagePNGRepresentation(image);}/**

*? 返回截取到的圖片

*

*? @return UIImage *

*/- (UIImage*)imageWithScreenshot{NSData*imageData = [selfdataWithScreenshotInPNGFormat];return[UIImageimageWithData:imageData];}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內容