天天看點

IOS應用開發-圖檔處理(拉伸圖檔 建立縮略圖 解決圖檔旋轉的問題 圖檔編碼及上傳 将圖檔寫入磁盤)

在做項目時我們經常要對圖檔進行一些處理,以達到性能優化或滿足需求。常見的情形有以下幾種

拉伸圖檔

項目中使用的圖檔素材如果能通過拉伸獲得就盡量這樣去做。這樣做有兩個顯而易見的好處,一是能夠減少App安裝包的大小,另外一個則是減少App運作時占據的記憶體空間大小。畢竟App的UI基本上來說是建立在大量的精緻的圖檔上,如果這些圖檔都一概使用螢幕等大小的圖檔,那麼對App的性能及安裝量都是有一定的負面影響的。

對于拉伸圖檔,适配ios 5及之後可以使用

1

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets

這個方法隻接收一個UIEdgeInsets類型的參數,可以通過設定UIEdgeInsets的top、left、bottom、right來分别指定上端蓋高度、左端蓋寬度、下端蓋高度、右端蓋寬度。這個端蓋的距離值是用機關pt(點,point)衡量的,在普通顯示屏中,1pt = 1pix;在retina顯示屏中,1pt = 2pix。還有一個需要注意的地方,如果端蓋距離值不是整數的話,拉伸後的圖檔會有白條細線。

建立縮略圖

如果有一張大圖,我們隻想要顯示它的指定大小的縮略圖内容,可以這樣做:在UIImage的類别中實作如下方法,調用方法建立縮略圖

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

- (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;

}

解決圖檔旋轉的問題

ios程式中使用系統相機拍照和從相冊選取圖檔,直接上傳後在非mac系統下看到的圖檔會發生旋轉的現象,那是因為我們沒有通過圖檔的旋轉屬性修改圖檔轉向。可以用下面的方法解決這個問題:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

@interface

UIImage (fixOrientation)

- (UIImage *)fixOrientation;

@end

@implementation

UIImage (fixOrientation)

- (UIImage *)fixOrientation {

// No-op if the orientation is already correct

if

(self.imageOrientation == UIImageOrientationUp)

return

self;

// We need to calculate the proper transformation to make the image upright.

// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.

CGAffineTransform transform = CGAffineTransformIdentity;

switch

(self.imageOrientation) {

case

UIImageOrientationDown:

case

UIImageOrientationDownMirrored:

transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);

transform = CGAffineTransformRotate(transform, M_PI);

break

;

case

UIImageOrientationLeft:

case

UIImageOrientationLeftMirrored:

transform = CGAffineTransformTranslate(transform, self.size.width,

);

transform = CGAffineTransformRotate(transform, M_PI_2);

break

;

case

UIImageOrientationRight:

case

UIImageOrientationRightMirrored:

transform = CGAffineTransformTranslate(transform,

, self.size.height);

transform = CGAffineTransformRotate(transform, -M_PI_2);

break

;

}

switch

(self.imageOrientation) {

case

UIImageOrientationUpMirrored:

case

UIImageOrientationDownMirrored:

transform = CGAffineTransformTranslate(transform, self.size.width,

);

transform = CGAffineTransformScale(transform, -

1

,

1

);

break

;

case

UIImageOrientationLeftMirrored:

case

UIImageOrientationRightMirrored:

transform = CGAffineTransformTranslate(transform, self.size.height,

);

transform = CGAffineTransformScale(transform, -

1

,

1

);

break

;

}

// Now we draw the underlying CGImage into a new context, applying the transform

// calculated above.

CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,

CGImageGetBitsPerComponent(self.CGImage),

,

CGImageGetColorSpace(self.CGImage),

CGImageGetBitmapInfo(self.CGImage));

CGContextConcatCTM(ctx, transform);

switch

(self.imageOrientation) {

case

UIImageOrientationLeft:

case

UIImageOrientationLeftMirrored:

case

UIImageOrientationRight:

case

UIImageOrientationRightMirrored:

// Grr...

CGContextDrawImage(ctx, CGRectMake(

,

,self.size.height,self.size.width), self.CGImage);

break

;

default

:

CGContextDrawImage(ctx, CGRectMake(

,

,self.size.width,self.size.height), self.CGImage);

break

;

}

// And now we just create a new UIImage from the drawing context

CGImageRef cgimg = CGBitmapContextCreateImage(ctx);

UIImage *img = [UIImage imageWithCGImage:cgimg];

CGContextRelease(ctx);

CGImageRelease(cgimg);

return

img;

}

@end

圖檔編碼及上傳

有時候我們會需要将圖檔資料以字元串的形式上傳到伺服器。在将UIImage對象轉化為NSData再轉化為NSString的時候,NSString對象中會出現有亂碼的情況,這個時候再将NSData轉化為NSString之前要編碼NSData對象

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

#

import

"UIImage+Ext.h"

#

import

"GTMBase64.h"

@interface

UIImage (Ext)

- (NSString *)convertToString;

@end

@implementation

UIImage (Ext)

- (NSString *)convertToString

{

if

(!self) {

return

nil;

}

NSData *imgData = UIImageJPEGRepresentation(self,

0.5

);

NSData *encode = [GTMBase64 encodeData:imgData];

// base64編碼NSData(解決亂碼問題)

NSString *imgStr = [[NSString alloc] initWithData:encode encoding:NSUTF8StringEncoding];

return

imgStr;

}

@end

将圖檔寫入磁盤

要将圖檔存儲到本地磁盤中,需要先把圖檔對象轉化為NSData對象,然後調用writeToFile:接口寫入

1

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;