iPhone IOS區域截圖


轉載:http://talentwsc.blog.163.com/blog/static/68743076201231322844508/

在ios開發中,肯定會碰到需要截取部分圖片的情況。

最終的效果類似這樣:

imageimage

先看最原始的示例,顯示完整的圖片

寫了個最簡單的讀取圖片並顯示的代碼,打算以此為開始,逐漸實現截取部分圖片的功能。

代碼主要是,在控制器代碼中:

- (void)loadView { 
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide]; 
    UIImage *image=[UIImage imageNamed:@"1.jpg"]; 
    
    UIImageView *contentView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    [contentView setImage:image]; 
    
    self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    [self.view addSubview:contentView]; 
}

另外,應該有一個名為1.jpg的768×1024的圖片(我這里是iPad)。

 

截取整個圖片

可以認為截取整個圖片是截取部分圖片的一個特例。對ios不熟嘛,因此打算很謹慎的推進。截取整個圖片可以減少中間的復雜性。

根據API,摸索着寫了一個示例,效果出乎意料:

image

代碼:

- (void)loadView { 
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide]; 
    UIImage *image=[UIImage imageNamed:@"1.jpg"]; 
    
    UIImageView *contentView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    //[contentView setImage:image]; 
    
    CGRect rect = CGRectMake(0, 0, 768, 1024);//創建矩形框 
    UIGraphicsBeginImageContext(rect.size);//根據size大小創建一個基於位圖的圖形上下文 
    CGContextRef currentContext = UIGraphicsGetCurrentContext();//獲取當前quartz 2d繪圖環境 
    CGContextClipToRect( currentContext, rect);//設置當前繪圖環境到矩形框 
    
    CGContextDrawImage(currentContext, rect, image.CGImage);//繪圖 
    UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();//獲得圖片 
    UIGraphicsEndImageContext();//從當前堆棧中刪除quartz 2d繪圖環境 
    
    contentView.image=cropped; 
    
    self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    [self.view addSubview:contentView];

    [cropped release]; 
}

這個代碼說明了兩點:

  • 好的方面:說明我的代碼起作用了,確實截取了所需的圖形
  • 壞的方面:圖形是顛倒的,而且是鏡像的。

問題應該出在坐標系上。下面畫了一個quartz 2d的坐標系,坐標原點在左下角:

image

因此以這個坐標系取圖形,就會有轉向180°的效果。

其實如果是對圖片的縮放,而不是剪切部分圖片內容,這樣寫就可以了:

- (void)loadView { 
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide]; 
    UIImage *image=[UIImage imageNamed:@"1.jpg"]; 
    
    //[contentView setImage:image]; 
    
    CGRect rect = CGRectMake(0, 0, 384, 512);//創建矩形框 
    UIGraphicsBeginImageContext(rect.size);//根據size大小創建一個基於位圖的圖形上下文 
    CGContextRef currentContext = UIGraphicsGetCurrentContext();//獲取當前quartz 2d繪圖環境 
    CGContextClipToRect(currentContext, rect);//設置當前繪圖環境到矩形框 
    
    //CGContextRotateCTM(currentContext, 50); 
    
    //CGContextDrawImage(currentContext, rect, image.CGImage);//繪圖 
    
    [image drawInRect:rect]; 
    
    UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();//獲得圖片 
    UIGraphicsEndImageContext();//從當前堆棧中刪除quartz 2d繪圖環境 
    
    UIImageView *contentView = [[UIImageView alloc] initWithFrame:rect]; 
    contentView.image=cropped; 
    
    self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    [self.view addSubview:contentView];

    [cropped release]; 
}

效果類似這樣:

image

這個方法可以幫助我們在后續開發中實現縮略圖。但是不符合現在的需求。

於是想了下面的基本思路:

image

這樣,需要一個能旋轉和向下移動的API。ios提供了C++界面的函數調用:

  • CGContextRotateCTM,實現角度的轉換
  • CGContextTranslateCTM,可以重新設置坐標系原點,平移坐標系和移動圖片是等效的

代碼:

- (void)loadView { 
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide]; 
    UIImage *image=[UIImage imageNamed:@"1.jpg"]; 
    
    //[contentView setImage:image]; 
    
    CGRect rect = CGRectMake(0, 0, 384, 512);//創建矩形框 
    UIGraphicsBeginImageContext(rect.size);//根據size大小創建一個基於位圖的圖形上下文 
    CGContextRef currentContext = UIGraphicsGetCurrentContext();//獲取當前quartz 2d繪圖環境 
    CGContextClipToRect(currentContext, rect);//設置當前繪圖環境到矩形框 
    
    CGContextRotateCTM(currentContext, M_PI); 
    CGContextTranslateCTM(currentContext, -rect.size.width, -rect.size.height); 
    
    CGContextDrawImage(currentContext, rect, image.CGImage);//繪圖 
    
    //[image drawInRect:rect]; 
    
    UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();//獲得圖片 
    UIGraphicsEndImageContext();//從當前堆棧中刪除quartz 2d繪圖環境 
    
    UIImageView *contentView = [[UIImageView alloc] initWithFrame:rect]; 
    contentView.image=cropped; 
    
    self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    [self.view addSubview:contentView];

    [cropped release]; 
}

image

這個結果還有缺陷,可以看到圖片是正立的了,但是圖片反轉了,是個鏡像。

解決辦法也有,不過不是操作圖片了,而是操作圖片所在的視圖。思路是把視圖看作一個位圖的矩陣,對它做矩陣變換運算,使視圖做鏡像反轉。寫法很簡單:

- (void)loadView { 
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide]; 
    UIImage *image=[UIImage imageNamed:@"1.jpg"]; 
    
    //[contentView setImage:image]; 
    
    CGRect rect = CGRectMake(0, 0, 384, 512);//創建矩形框 
    UIGraphicsBeginImageContext(rect.size);//根據size大小創建一個基於位圖的圖形上下文 
    CGContextRef currentContext = UIGraphicsGetCurrentContext();//獲取當前quartz 2d繪圖環境 
    CGContextClipToRect(currentContext, rect);//設置當前繪圖環境到矩形框 
    
    
    CGContextRotateCTM(currentContext, M_PI); 
    CGContextTranslateCTM(currentContext, -rect.size.width, -rect.size.height); 
    //CGContextTranslateCTM(currentContext,0.0,200.0); 
    
    CGContextDrawImage(currentContext, rect, image.CGImage);//繪圖 
    
    //[image drawInRect:rect]; 
    
    UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();//獲得圖片 
    UIGraphicsEndImageContext();//從當前堆棧中刪除quartz 2d繪圖環境 
    
        
    UIImageView *contentView = [[UIImageView alloc] initWithFrame:rect]; 
    contentView.image=cropped; 
    
    contentView.transform = CGAffineTransformIdentity; 
    contentView.transform = CGAffineTransformMakeScale(-1.0, 1.0);

    
    self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    [self.view addSubview:contentView];

    [cropped release]; 
}

 

這里的轉換因子,一個是針對x軸的,一個是針對y軸的。終於可以產生這樣的效果了:

image

這里參考了這個文檔:

http://macdevcenter.com/pub/a/mac/2004/11/02/quartz.html

雖然是很古老的文章了,但是說的很清楚。另外,方法名稱已經發生變化,需要注意。

截取部分圖片

截取部分圖片,比如:

image

截取左邊人像部分。

實現后的代碼,效果是這樣的:

image

如何實現的呢,這時候才發現,其實根本不需要上面那些轉換,如果不使用quartz 2d的話,截取部分圖片這么簡單:

- (void)loadView { 
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation: UIStatusBarAnimationSlide]; 
    UIImage *image=[UIImage imageNamed:@"1.jpg"]; 
    
    
    CGRect rect = CGRectMake(60, 80, 331, 353);//創建矩形框 
    UIImageView *contentView = [[UIImageView alloc] initWithFrame:rect]; 
    contentView.image=[UIImage imageWithCGImage:CGImageCreateWithImageInRect([image CGImage], rect)]; 
    
    self.view=[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    [self.view addSubview:contentView]; 
    
    [image release]; 
}

雖然編寫代碼的過程是曲折的,但是摸到很多有用的東西,都是以后要用到的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM