最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS中大尺寸圖片的旋轉(zhuǎn)與縮放實例詳解

 更新時間:2018年09月05日 09:42:51   作者:BourbonZ  
圖片縮小旋轉(zhuǎn)是我們在開發(fā)中經(jīng)常會遇到的一個功能,下面這篇文章主要給大家介紹了關于iOS中大尺寸圖片的旋轉(zhuǎn)與縮放的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧

前言

由于iPhone的硬件性能限制,直到iPhone 6s開始,才將最大內(nèi)存拓展到2G。

可即使是如此,也不代表一個應用可使用的空間是2G。

一張10000 x 10000的圖片,如果通過UIImageJPEGRepresentation方法將圖片轉(zhuǎn)成內(nèi)存數(shù)據(jù),會有一個峰值波動。

這里的峰值其實是圖片在解壓時產(chǎn)生的位圖數(shù)據(jù)所占空間,然后才轉(zhuǎn)換成我們可以操作的NSData。

其計算公式是 W x H x 4 / 1024 / 1024 也就是 10000 x 10000 x4 /1024 / 1024 = 381.4(M)。

這里會產(chǎn)生381M的消耗,及時會被回收,但是想一下,如果圖片尺寸很大,數(shù)量很多的時候,很容易就會發(fā)生異常了。

本文將給大家詳細介紹關于iOS大尺寸圖片旋轉(zhuǎn)與縮放的相關內(nèi)容,分享出來供大家參考學習,話不多說了,接下來說下具體的操作

旋轉(zhuǎn)

我們知道如果對一個UIImage對象進行旋轉(zhuǎn)操作,相信做項目時肯定會有用到 UIImage 這個類,可以有如下的方式

通過 CGContextDrawImage 進行圖片繪制

+ (UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation {

 long double rotate = 0.0;
 CGRect rect;
 float translateX = 0;
 float translateY = 0;
 float scaleX = 1.0;
 float scaleY = 1.0;

 switch (orientation) {
 case UIImageOrientationLeft:
 rotate = M_PI_2;
 rect = CGRectMake(0, 0, image.size.height, image.size.width);
 translateX = 0;
 translateY = -rect.size.width;
 scaleY = rect.size.width/rect.size.height;
 scaleX = rect.size.height/rect.size.width;
 break;
 default:
 rotate = 0.0;
 rect = CGRectMake(0, 0, image.size.width, image.size.height);
 translateX = 0;
 translateY = 0;
 break;
 }

 UIGraphicsBeginImageContext(rect.size);
 CGContextRef context = UIGraphicsGetCurrentContext();
 //做CTM變換
 CGContextTranslateCTM(context, 0.0, rect.size.height);
 CGContextScaleCTM(context, 1.0, -1.0);
 CGContextRotateCTM(context, rotate);
 CGContextTranslateCTM(context, translateX, translateY);

 CGContextScaleCTM(context, scaleX, scaleY);
 //繪制圖片
 CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
 UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
 return newPic;
} 

這里有一個問題是,這里會創(chuàng)建一個新的圖片大小空間的,然后進行重新繪制??赡軙嬖谝粋€隱患,就是當圖片尺寸過大的時候,就會出現(xiàn)內(nèi)存占用過高的情況

接下來介紹一種另辟蹊徑的解決方法--通過給圖片添加濾鏡的方式。

既然操作的對象是圖片,那么它就會各種濾鏡展示。系統(tǒng)給我們提供了多大一百多種濾鏡,這里的濾鏡不單只顏色等狀態(tài)發(fā)生變化。

這其中就有我們需要的濾鏡Key inputTransform。

+ (UIImage *)getRotationImage:(UIImage *)image rotation:(CGFloat)rotation {

 CIImage *ciImage = [[CIImage alloc] initWithImage:image];
 CIFilter *filter = [CIFilter filterWithName:@"CIAffineTransform" keysAndValues:kCIInputImageKey, ciImage, nil];

 [filter setDefaults];
 CGAffineTransform transform = CATransform3DGetAffineTransform([self rotateTransform:CATransform3DIdentity clockwise:NO angle:rotation]);
 [filter setValue:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKey:@"inputTransform"];

 //根據(jù)濾鏡設置圖片
 CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(NO)}];
 CIImage *outputImage = [filter outputImage];
 CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];

 UIImage *result = [UIImage imageWithCGImage:cgImage];

 CGImageRelease(cgImage);

 return result;
}
+ (CATransform3D)rotateTransform:(CATransform3D)initialTransform clockwise:(BOOL)clockwise angle:(CGFloat)angle {

 CGFloat arg = angle*M_PI / 180.0f;
 if(!clockwise){
 arg *= -1;
 }
 //進行形變
 CATransform3D transform = initialTransform;
 transform = CATransform3DRotate(transform, arg, 0, 0, 1);
 CGFloat _flipState1 = 0;
 CGFloat _flipState2 = 0;
 transform = CATransform3DRotate(transform, _flipState1*M_PI, 0, 1, 0);
 transform = CATransform3DRotate(transform, _flipState2*M_PI, 1, 0, 0);

 return transform;
} 

通過這種操作,可以利用GPU來進行圖片操作,可以一定程度的降低消耗,節(jié)約資源。

縮放

既然圖片很大,那么我們可以通過縮放的方式,來減小圖片的尺寸,減少內(nèi)存消耗,進而降低異常風險。

我們通常采用UIImage提供的系統(tǒng)方法drawInRect 及其一系列的方法,來進行圖片縮放。

可是這種操作的缺陷和最開始介紹的旋轉(zhuǎn)一樣,其實質(zhì)都是進行圖片的重新繪制。

通過繪制圖片的方式進行圖片縮放

+ (UIImage *)image:(UIImage *)image transformtoSize:(CGSize)Newsize {
 // 創(chuàng)建一個bitmap的context
 UIGraphicsBeginImageContext(Newsize);
 // 繪制改變大小的圖片
 [image drawInRect:CGRectMake(0, 0, Newsize.width, Newsize.height)];
 // 從當前context中創(chuàng)建一個改變大小后的圖片
 UIImage *TransformedImg=UIGraphicsGetImageFromCurrentImageContext();
 // 使當前的context出堆棧
 UIGraphicsEndImageContext();
 // 返回新的改變大小后的圖片
 return TransformedImg;
}

這里是內(nèi)存消耗。通過看圖可以發(fā)現(xiàn),針對大圖,在進行縮放的時候,內(nèi)存消耗的峰值能達到426M,耗時在1.5s左右
由于我們使用的手機是iPhone X,在更低端的設備上,這是多么大的損耗,很容易發(fā)生異常

既然上面的方法損耗很大,我們來看下另外的一種方式。

先看下內(nèi)存消耗

通過圖上可以看出,在進行圖片縮放的時候,內(nèi)存有小幅增加,產(chǎn)生的消耗在18M,耗時也在1.5s左右。

這樣的效果是非常顯著的。下面來看代碼

+(UIImage *)resizeImage:(UIImage *)image toSize:(CGSize)size {

 CIImage *ciImage = [[CIImage alloc] initWithImage:image];
 //創(chuàng)建一個input image類型的濾鏡
 CIFilter *filter = [CIFilter filterWithName:@"CIAffineTransform" keysAndValues:kCIInputImageKey, ciImage, nil];
 //設置默認的濾鏡效果
 [filter setDefaults];

 //設置縮放比例
 CGFloat scale = 1;
 if (size.width != CGFLOAT_MAX) {
 scale = (CGFloat) size.width / image.size.width;
 } else if (size.height != CGFLOAT_MAX) {
 scale = (CGFloat) size.height / image.size.height;
 }

 //進行賦值
 CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale);
 [filter setValue:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKey:@"inputTransform"];

 //通過GPU的方式來進行處理
 CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(NO)}];
 //根據(jù)濾鏡輸出圖片
 CIImage *outputImage = [filter outputImage];
 CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
 //創(chuàng)建UIImage 對象,并釋放資源
 UIImage *result = [UIImage imageWithCGImage:cgImage];

 CGImageRelease(cgImage);

 return result;
}

可以發(fā)現(xiàn)我們這里使用的和旋轉(zhuǎn)是同樣的方式。通過給圖片添加濾鏡能夠很安全的實現(xiàn)我們的需求。

總結(jié)

1.針對巨幅圖片操作,可以采用這種思路:先生成一個尺寸小的縮略圖,然后在進行各種操作,可以降低資源消耗;

2.通過CoreImage.framework來進行圖片處理。

3.之前一直對CoreImage.framework的理解,只是其能夠?qū)D片和視頻添加那種可見的濾鏡,未曾想過這種濾鏡也支持縮放和旋轉(zhuǎn)。

? 為什么CoreImage.framework的方式能夠很安全呢?

該框架從iOS 5開始投入使用,通過對CoreGraphics.framework、CoreVideo.framework、Image I/O.framework進行數(shù)據(jù)處理,

可以自由在CPU和GPU之間切換運算方式,

可以最大限度的利用GPU來進行計算,降低內(nèi)存消耗,

甚至可以對視頻進行實時濾鏡處理。

針對不能通過原生對UIView進行transform操作的時候,CoreImage.framework會是你的朋友。

最直接的來自文檔

Core Image is an image processing and analysis technology designed to provide near real-time processing for still and video images. It operates on image data types from the Core Graphics, Core Video, and Image I/O frameworks, using either a GPU or CPU rendering path. Core Image hides the details of low-level graphics processing by providing an easy-to-use application programming interface (API). You don't need to know the details of OpenGL, OpenGL ES, or Metal to leverage the power of the GPU, nor do you need to know anything about Grand Central Dispatch (GCD) to get the benefit of multicore processing. Core Image handles the details for you.

它已經(jīng)幫你把所有東西都處理好了,大膽的用吧

代碼地址 (本地下載

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • iOS開發(fā)中Quartz2D控制圓形縮放和實現(xiàn)刷幀效果

    iOS開發(fā)中Quartz2D控制圓形縮放和實現(xiàn)刷幀效果

    這篇文章主要介紹了iOS開發(fā)中Quartz2D控制圓形縮放和實現(xiàn)刷幀效果的方法,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2015-12-12
  • 實例解析iOS開發(fā)中系統(tǒng)音效以及自定義音效的應用

    實例解析iOS開發(fā)中系統(tǒng)音效以及自定義音效的應用

    這篇文章主要介紹了iOS開發(fā)中系統(tǒng)音效以及自定義音效的應用,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2015-10-10
  • iOS輕點、觸摸和手勢代碼開發(fā)

    iOS輕點、觸摸和手勢代碼開發(fā)

    這篇文章主要為大家詳細介紹了iOS輕點、觸摸和手勢代碼開發(fā),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • iOS開發(fā)學習之監(jiān)測程序的崩潰次數(shù)詳解

    iOS開發(fā)學習之監(jiān)測程序的崩潰次數(shù)詳解

    iOS開發(fā)中遇到程序崩潰是很正常的事情,下面這篇文章主要給大家介紹了關于iOS如何監(jiān)測程序崩潰次數(shù)的相關資料,文中通過詳細的示例代碼供大家參考學習,需要的朋友們下面跟著小編來一起學習學習吧。
    2017-07-07
  • ios原生二維碼掃描

    ios原生二維碼掃描

    本文給大家介紹ios原生二維碼掃描,有需要的朋友可以參考下
    2015-09-09
  • iOS內(nèi)存錯誤EXC_BAD_ACCESS的解決方法

    iOS內(nèi)存錯誤EXC_BAD_ACCESS的解決方法

    iOS開發(fā),最郁悶的莫過于程序毫無征兆地就崩潰了,用bt命令打出調(diào)用棧,給出的是一堆系統(tǒng)EXC_BAD_ACCESS的信息,根本沒辦法定位問題出現(xiàn)在哪里
    2013-06-06
  • IOS定制屬于自己的個性頭像

    IOS定制屬于自己的個性頭像

    這篇文章主要為大家介紹了IOS定制屬于自己的個性頭像,實現(xiàn)方法很簡單,感興趣的小伙伴們可以參考一下
    2016-01-01
  • 簡單說說iOS之WKWebView的用法小結(jié)

    簡單說說iOS之WKWebView的用法小結(jié)

    iOS8.0之后我們使用 WebKit框架中的WKWebView來加載網(wǎng)頁。這篇文章主要介紹了簡單說說iOS之WKWebView的用法小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • iOS中捕獲日志與異常示例詳解

    iOS中捕獲日志與異常示例詳解

    在日常的工作中,日志是不可缺少的一個環(huán)節(jié),下面這篇文章主要給大家介紹了iOS中捕獲日志與異常的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-04-04
  • iOS10最新實現(xiàn)遠程通知的開發(fā)教程詳解

    iOS10最新實現(xiàn)遠程通知的開發(fā)教程詳解

    這篇文章主要介紹了iOS10最新遠程通知開發(fā)的實現(xiàn)過程,文章先對推送通知以及遠程推送通知等進行了基本介紹,然后通過示例代碼詳細介紹了iOS10 全新遠程通知的教程,有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-09-09

最新評論

兰溪市| 泰宁县| 长沙县| 永胜县| 光山县| 改则县| 敦煌市| 佛教| 柘荣县| 沁阳市| 慈利县| 合川市| 武隆县| 五常市| 鞍山市| 繁昌县| 故城县| 肃宁县| 龙海市| 手游| 西贡区| 宜州市| 旌德县| 贺州市| 黄龙县| 神农架林区| 金溪县| 柏乡县| 电白县| 廊坊市| 吉水县| 聂拉木县| 循化| 扶余县| 铜梁县| 平果县| 河东区| 镇宁| 福建省| 临安市| 平远县|