http://mp.weixin.qq.com/s/A900w0Y5pGjuaB4j9Os9ww1、UIImage 生成方法的對比
Apple官方的文檔為生成一個UIImage對象提供了兩種方法:
1. imageNamed,其參數為圖片的名字;優點:加載時會緩存圖片,用於圖片的頻繁使用;缺點:占用內存,直到應用結束
2. imageWithContentsOfFile,其參數也是圖片文件的路徑。優點:僅加載圖片,不會緩存,用於價值次數較少的情況,降低內存消耗
那么兩種有什么區別嗎?
肯定是有的。根據Apple的官方文檔:
imageNamed
: 這個方法用一個指定的名字在系統緩存中查找並返回一個圖片對象如果它存在的話。如果緩存中沒有找到相應的圖片,這個方法從指定的文檔中加載然后緩存並返回這個對象。因此imageNamed
的優點是當加載時會緩存圖片。所以當圖片會頻繁的使用時,那么用imageNamed
的方法會比較好。例如:你需要在 一個TableView里的TableViewCell里都加載同樣一個圖標,那么用imageNamed加載圖像效率很高。系統會把那個圖標Cache到內存,在TableViewCell里每次利用那個圖 像的時候,只會把圖片指針指向同一塊內存。正是因此使用imageNamed
會緩存圖片,即將圖片的數據放在內存中,iOS的內存非常珍貴並且在內存消耗過大時,會強制釋放內存,即會遇到memory warnings。而在iOS系統里面釋放圖像的內存是一件比較麻煩的事情,有可能會造成內存泄漏。例如:當一 個UIView對象的animationImages是一個裝有UIImage對象動態數組NSMutableArray,並進行逐幀動畫。當使用imageNamed的方式加載圖像到一個動態數組NSMutableArray,這將會很有可能造成內存泄露。原因很顯然的。
imageWithContentsOfFile
:僅加載圖片,圖像數據不會緩存。因此對於較大的圖片以及使用情況較少時,那就可以用該方法,降低內存消耗。
下面列舉出兩種方法的詳細用法:
- NSString *path = [[NSBundle mainBundle] pathForResource:@”icon” ofType:@”png”];
- UIImage *image = [UIImage imageWithContentsOfFile:path];
以及:
- NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:“png”];
- NSData *image = [NSData dataWithContentsOfFile:filePath];
- UIImage *image = [UIImage imageWithData:image]; //or = [UIImage imageWithContentsOfFile:filePath];
IOS中對圖片的處理 UIImage
相信做項目時肯定會有用到 UIImage 這個類,那我們就來看一下這個類中都有什么內容。
其實這篇文章就是在看文檔的時候想記錄一下文檔中得方法。
UIImage 繼承於
NSObject
下面介紹一下UIImage中的方法
首先是我們最常用的
通過圖片的文件名來獲取這個圖片
+ (UIImage *)imageNamed:(
NSString
*)name
//要注意的是這個方法適用於已經導入到工程中的圖片
創建新圖片
1、+ (UIImage *)imageWithContentsOfFile:(
NSString
*)path
//通過文件加載指定路徑下的文件內容獲得新圖片
2、+ (UIImage *)imageWithData:(
NSData
*)data
//通過一個NSData對象來獲得圖片
3、+ (UIImage *)imageWithData:(
NSData
*)data scale:(CGFloat)scale
//同上,只是再加上一個圖片大小比例,用來改變圖片的大小
4、+ (UIImage *)imageWithCGImage:(CGImageRef)cgImage
//使用Quartz 2D對象創建UIImage
5、+ (UIImage *)imageWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
//制定圖片的比例和方向,其中方向是個枚舉類。
6、+ (UIImage *)imageWithCIImage:(CIImage *)ciImage
//用一個Core Image 對象創建圖像
7、+ (UIImage *)imageWithCIImage:(CIImage *)ciImage scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
//再加上比例和圖片方向
8、- (UIImage *)imageWithAlignmentRectInsets:(UIEdgeInsets)alignmentInsets
//返回指定矩形區域內的圖像
9、+ (UIImage *)animatedImageNamed:(
NSString
*)name duration:(
NSTimeInterval
)duration
//創建一個動態圖片,動態圖片持續的時間為duration
10、+ (UIImage *)animatedImageWithImages:(
NSArray
*)images duration:(
NSTimeInterval
)duration
//用一組圖片創建一個動態圖片,動態持續時間duration
11、+ (UIImage *)animatedResizableImageNamed:(
NSString
*)name capInsets:(UIEdgeInsets)capInsets duration:(
NSTimeInterval
)duration
//創建一個在可變大小的圖片上指定矩形區域內的動態圖片
12、+ (UIImage *)animatedResizableImageNamed:(
NSString
*)name capInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode duration:(
NSTimeInterval
)duration
//同上,只是多了一個圖片變化的方式,具體來說就是平鋪或者拉伸
13、- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
//用制定矩形區域創建圖像
14、- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode
//同上,指定圖片變化方式
初始化圖片
方法的作用在從上面的一些方法中都能找到原型,這里就不一一注釋了
1、– initWithContentsOfFile:
//從文件加載圖片
2、– initWithData:
//用NSData對象初始化圖片
3、– initWithData:scale:
//用NSData對象,指定的比例,初始化圖片
4、– initWithCGImage:
5、– initWithCGImage:scale:orientation:
6、– initWithCIImage:
7、– initWithCIImage:scale:orientation:
繪畫圖片
1、– drawAtPoint:
//在指定的點開始繪畫圖片,這個點就是圖片的做上角頂點
2、- (
void
)drawAtPoint:(CGPoint)point blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha
//在指定的點繪制整個圖片,並使用自定義圖片復合模式,並設置透明度
3、– drawInRect:
//在指定區域內繪制圖片,可根據需要縮放圖片
4、– drawInRect:blendMode:alpha:
//參照上面第二條
5、– drawAsPatternInRect:
//在指定區域內,平鋪圖片
image的屬性
imageOrientation
//圖片的方向
size
//圖片的大小size
scale
//圖片的比例
resizingMode
//圖片變化方式
CGImage
//潛在的Quartz image
CIImage
//潛在的Core Image
images
//返回一個由圖片組成的數組,針對於由一組圖片生成的動態圖片
duration
//返回動態圖片持續的時間(即動態圖片播放一遍的時間)
capInsets
//圖片上選定的區域
alignmentRectInsets
//圖片平鋪的區域
iOS自帶的提供了一個API如下
[html] view plaincopy
NSData
*UIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality);
在Iphone上有兩種讀取圖片數據的簡單方法: UIImageJPEGRepresentation和UIImagePNGRepresentation. UIImageJPEGRepresentation函數需要兩個參數:圖片的引用和壓縮系數.而UIImagePNGRepresentation只需要圖片引用作為參數.通過在實際使用過程中,比較發現: UIImagePNGRepresentation(UIImage* image) 要比UIImageJPEGRepresentation(UIImage* image, 1.0) 返回的圖片數據量大很多.譬如,同樣是讀取攝像頭拍攝的同樣景色的照片, UIImagePNGRepresentation()返回的數據量大小為199K ,而 UIImageJPEGRepresentation(UIImage* image, 1.0)返回的數據量大小只為140KB,比前者少了50多KB.如果對圖片的清晰度要求不高,還可以通過設置 UIImageJPEGRepresentation函數的第二個參數,大幅度降低圖片數據量.譬如,剛才拍攝的圖片, 通過調用UIImageJPEGRepresentation(UIImage* image, 1.0)讀取數據時,返回的數據大小為140KB,但更改壓縮系數后,通過調用UIImageJPEGRepresentation(UIImage* image, 0.5)讀取數據時,返回的數據大小只有11KB多,大大壓縮了圖片的數據量 ,而且從視角角度看,圖片的質量並沒有明顯的降低.因此,在讀取圖片數據內容時,建議優先使用UIImageJPEGRepresentation,並可根據自己的實際使用場景,設置壓縮系數,進一步降低圖片數據量大小。
[html] view plaincopy
UIImage *imageNew = [info objectForKey:@
"UIImagePickerControllerOriginalImage"
];
imageNew = [
self
imageWithImage:imageNew scaledToSize:CGSizeMake(100, 100)];
NSData
*imageData = UIImageJPEGRepresentation(imageNew, 0.0001);
m_selectImage = [UIImage imageWithData:imageData];
.h具體code
[html] view plaincopy
#import <Foundation/Foundation.h>
@interface
UIImage (UIImageExt)
- (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size;
- (UIImage *)imageByScalingAndCroppingForSize:(CGSize)targetSize;
@end
.m具體code
[html] view plaincopy
#import "UIImageExt.h"
@implementation
UIImage (UIImageExt)
- (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{
// 創建一個bitmap的context
// 並把它設置成為當前正在使用的context
UIGraphicsBeginImageContext(size);
// 繪制改變大小的圖片
[img drawInRect:CGRectMake(0, 0, size.width, size.height)];
// 從當前context中創建一個改變大小后的圖片
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// 使當前的context出堆棧
UIGraphicsEndImageContext();
// 返回新的改變大小后的圖片
return
scaledImage;
}
- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{
UIImage *sourceImage =
self
;
UIImage *newImage =
nil
;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if
(CGSizeEqualToSize(imageSize, targetSize) ==
NO
)
{
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if
(widthFactor > heightFactor)
scaleFactor = widthFactor;
// scale to fit height
else
scaleFactor = heightFactor;
// scale to fit width
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if
(widthFactor > heightFactor)
{
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
}
else
if
(widthFactor < heightFactor)
{
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
UIGraphicsBeginImageContext(targetSize);
// this will crop
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
if
(newImage ==
nil
)
NSLog
(@
"could not scale image"
);
//pop the context to get back to the default
UIGraphicsEndImageContext();
return
newImage;
}
<br>
/** 返回一張經過處理的圖片*/
<br>+ (UIImage *)createCompressesImageWithName:(
NSString
*)imageName<br>{<br> <br> UIImage *newImage = [UIImage imageWithImageSimple:[UIImage imageWithName:imageName] scaledToSize:[UIImage imageWithName:imageName].size];<br><br>
return
newImage;<br>}<br>
@end