自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

利用預(yù)渲染加速iOS設(shè)備的圖像顯示

移動開發(fā) iOS
本文將講述《利用預(yù)渲染加速iOS設(shè)備的圖像顯示》。在iOS平臺上開發(fā)UITableView的滾動性能還不錯,但來回滾動時,第一次顯示的圖像不如再次顯示的圖像流暢,出現(xiàn)前會有稍許的停頓感。作者教給我們一個利用預(yù)渲染加速iOS設(shè)備的圖像顯示方法來解決這個問題。

最近在做一個UITableView的例子,發(fā)現(xiàn)滾動時的性能還不錯。但來回滾動時,第一次顯示的圖像不如再次顯示的圖像流暢,出現(xiàn)前會有稍許的停頓感。

于是我猜想顯示過的圖像肯定是被緩存起來了,查了下文檔后發(fā)現(xiàn)果然如此。

后來在別的文章中找到了一些提示:原來在顯示圖像時,解壓和重采樣會消耗很多CPU時間;而如果預(yù)先在一個bitmap context里畫出圖像,再緩存這個圖像,就能省去這些繁重的工作了。

接著我就寫了個例子程序來驗(yàn)證:

  1. //  ImageView.h 
  2.  
  3. #import <UIKit/UIKit.h> 
  4.  
  5.  
  6. @interface ImageView : UIView { 
  7.     UIImage *image; 
  8.  
  9. @property (retain, nonatomic) UIImage *image; 
  10.  
  11. @end 
  1. //  ImageView.m 
  2.  
  3. #include <mach/mach_time.h> 
  4. #import "ImageView.h" 
  5.  
  6.  
  7. @implementation ImageView 
  8.  
  9. #define LABEL_TAG 1 
  10.  
  11. static const CGRect imageRect = {{0, 0}, {100, 100}}; 
  12. static const CGPoint imagePoint = {0, 0}; 
  13.  
  14. @synthesize image; 
  15.  
  16. - (void)awakeFromNib { 
  17.     if (!self.image) { 
  18.         self.image = [UIImage imageNamed:@"random.jpg"]; 
  19.     } 
  20.  
  21. - (void)drawRect:(CGRect)rect { 
  22.     if (CGRectEqualToRect(rect, imageRect)) { 
  23.         uint64_t start = mach_absolute_time(); 
  24.         [image drawAtPoint:imagePoint]; 
  25.         uint64_t drawTime = mach_absolute_time() - start; 
  26.          
  27.         NSString *text = [[NSString alloc] initWithFormat:@"%ld", drawTime]; 
  28.         UILabel *label = (UILabel *)[self viewWithTag:LABEL_TAG]; 
  29.         label.text = text; 
  30.         [text release]; 
  31.     } 
  32.  
  33. - (void)dealloc { 
  34.     [super dealloc]; 
  35.     [image release]; 
  36.  
  37. @end 

控制器的代碼我就不列出了,就是點(diǎn)按鈕時,更新view(調(diào)用[self.view setNeedsDisplayInRect:imageRect]),畫出一張圖,并在label中顯示消耗的時間。

值得一提的是,在模擬器上可以直接用clock()函數(shù)獲得微秒級的精度,但iOS設(shè)備上精度為10毫秒。于是我找到了mach_absolute_time(),它在Mac和iOS設(shè)備上都有納秒級的精度。

測試用的是一張200x200像素的JPEG圖像,命名時加了@2x,在iPhone 4上第一次顯示時花了約300微秒,再次顯示約65微秒。

接下來就是見證奇跡的時刻了,把這段代碼加入程序:

  1. static const CGSize imageSize = {100, 100}; 
  2.  
  3. - (void)awakeFromNib { 
  4.     if (!self.image) { 
  5.         self.image = [UIImage imageNamed:@"random.jpg"]; 
  6.         if (NULL != UIGraphicsBeginImageContextWithOptions) 
  7.             UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0); 
  8.         else 
  9.             UIGraphicsBeginImageContext(imageSize); 
  10.         [image drawInRect:imageRect]; 
  11.         self.image = UIGraphicsGetImageFromCurrentImageContext(); 
  12.         UIGraphicsEndImageContext(); 
  13.     } 

這里需要判斷一下UIGraphicsBeginImageContextWithOptions是否為NULL,因?yàn)樗莍OS 4.0才加入的。

由于JPEG圖像是不透明的,所以第二個參數(shù)就設(shè)為YES。

第三個參數(shù)是縮放比例,iPhone 4是2.0,其他是1.0。雖然這里可以用[UIScreen mainScreen].scale來獲取,但實(shí)際上設(shè)為0后,系統(tǒng)就會自動設(shè)置正確的比例了。

值得一提的是,圖像本身也有縮放比例,普通的圖像是1.0(除了UIImage imageNamed:外,大部分API都只能獲得這種圖像,而且縮放比例是不可更改的),高清圖像是2.0。圖像的點(diǎn)和屏幕的像素就是依靠2者的縮放比例來計(jì)算的,例如普通圖像在視網(wǎng)膜顯示屏上是1:4,而高清圖像在視網(wǎng)膜顯示屏上則是1:1。

接下來的drawInRect:把圖像畫到了當(dāng)前的image context里,這時就完成了解壓縮和重采樣的工作了。然后再從image context里獲取新的image,這個image的縮放比例也能正確地和設(shè)備匹配。

再點(diǎn)下按鈕,發(fā)現(xiàn)時間已經(jīng)縮短到12微秒左右了,之后的畫圖穩(wěn)定在15微秒左右。

還能更快嗎?讓我們來試試Core Graphics。

先定義一個全局的CGImageRef變量:

  1. static CGImageRef imageRef; 

再在awakeFromNib中設(shè)置一下它的值:

  1. imageRef = self.image.CGImage; 

最后在drawRect:中繪制:

  1. CGContextRef context = UIGraphicsGetCurrentContext(); 
  2. CGContextDrawImage(context, imageRect, imageRef); 

搞定運(yùn)行一下,發(fā)現(xiàn)時間增加到33微秒左右了,而且圖像還上下顛倒了⋯

這個原因是UIKit和Core Graphics的坐標(biāo)系y軸是相反的,于是加上2行代碼來修正:

  1. CGContextRef context = UIGraphicsGetCurrentContext(); 
  2. CGContextTranslateCTM(context, 0, 100); 
  3. CGContextScaleCTM(context, 1, -1); 
  4. CGContextDrawImage(context, imageRect, imageRef); 

這下圖像終于正常顯示了,時間縮短到了14微秒左右,成效不大,看來直接用-drawAtPoint:和-drawInRect:也足夠好了。當(dāng)然,這個例子正確的做法是用viewDidLoad或loadView,不過我懶得列出控制器代碼,所以就放awakeFromNib里了。

責(zé)任編輯:佚名 來源: keakon的涂鴉館
相關(guān)推薦

2011-03-08 09:28:10

iOS4.3iOSiPad

2010-08-03 13:56:57

路由器連接

2011-07-29 11:04:52

2014-11-11 10:05:04

2012-04-24 23:31:41

iOS

2011-03-25 11:25:26

Cacti圖像

2017-02-20 19:25:54

Python 圖像處理

2015-06-08 09:06:53

DevOps軟件交付

2012-08-07 09:06:57

iOS SDK使用指南UIDeviceNSLocale

2012-04-24 15:07:49

HTML5

2012-05-25 09:14:31

虛擬化虛擬設(shè)備桌面虛擬化

2013-08-29 11:21:19

Firefox OSiOSAndroid

2009-07-31 18:28:46

實(shí)現(xiàn)C#顯示圖像

2023-10-07 15:51:56

2022-03-18 08:59:45

TestFlight蘋果漏洞

2014-04-03 14:15:45

XenDesktopWindows XP遷

2021-09-24 21:13:02

數(shù)字化轉(zhuǎn)型首席執(zhí)行官技術(shù)

2015-12-30 14:16:05

iOS動畫視圖渲染

2015-12-23 09:16:33

ios動畫渲染機(jī)制

2014-04-03 10:58:30

Citrix
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號