1. 程式人生 > >IOS應用開發-圖片處理(拉伸圖片 建立縮圖 解決圖片旋轉的問題 圖片編碼及上傳 將圖片寫入磁碟)

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

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

//http://stackoverflow.com/questions/5427656/ios-uiimagepickercontroller-result-image-orientation-after-upload

拉伸圖片

專案中使用的圖片素材如果能通過拉伸獲得就儘量這樣去做。這樣做有兩個顯而易見的好處,一是能夠減少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(); returnnewImage; }
解決圖片旋轉的問題

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 @interfaceUIImage (fixOrientation) - (UIImage *)fixOrientation; @end @implementationUIImage (fixOrientation) - (UIImage *)fixOrientation { // No-op if the orientation is already correct if(self.imageOrientation == UIImageOrientationUp) returnself; // 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) { caseUIImageOrientationDown: caseUIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); transform = CGAffineTransformRotate(transform, M_PI); break; caseUIImageOrientationLeft: caseUIImageOrientationLeftMirrored: transform = CGAffineTransformTranslate(transform, self.size.width,0); transform = CGAffineTransformRotate(transform, M_PI_2); break; caseUIImageOrientationRight: caseUIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform,0, self.size.height); transform = CGAffineTransformRotate(transform, -M_PI_2); break; } switch(self.imageOrientation) { caseUIImageOrientationUpMirrored: caseUIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, self.size.width,0); transform = CGAffineTransformScale(transform, -1,1); break; caseUIImageOrientationLeftMirrored: caseUIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, self.size.height,0); 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),0, CGImageGetColorSpace(self.CGImage), CGImageGetBitmapInfo(self.CGImage)); CGContextConcatCTM(ctx, transform); switch(self.imageOrientation) { caseUIImageOrientationLeft: caseUIImageOrientationLeftMirrored: caseUIImageOrientationRight: caseUIImageOrientationRightMirrored: // Grr... CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage); break; default: CGContextDrawImage(ctx, CGRectMake(0,0,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); returnimg; } @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" @interfaceUIImage (Ext) - (NSString *)convertToString; @end @implementationUIImage (Ext) - (NSString *)convertToString { if(!self) { returnnil; } NSData *imgData = UIImageJPEGRepresentation(self,0.5); NSData *encode = [GTMBase64 encodeData:imgData];// base64編碼NSData(解決亂碼問題) NSString *imgStr = [[NSString alloc] initWithData:encode encoding:NSUTF8StringEncoding]; returnimgStr; } @end
將圖片寫入磁碟

要將圖片儲存到本地磁碟中,需要先把圖片物件轉化為NSData物件,然後呼叫writeToFile:介面寫入

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