IOS應用開發-圖片處理(拉伸圖片 建立縮圖 解決圖片旋轉的問題 圖片編碼及上傳 將圖片寫入磁碟)
阿新 • • 發佈:2019-01-11
在做專案時我們經常要對圖片進行一些處理,以達到效能優化或滿足需求。常見的情形有以下幾種
//http://stackoverflow.com/questions/5427656/ios-uiimagepickercontroller-result-image-orientation-after-upload
拉伸圖片
專案中使用的圖片素材如果能通過拉伸獲得就儘量這樣去做。這樣做有兩個顯而易見的好處,一是能夠減少App安裝包的大小,另外一個則是減少App執行時佔據的記憶體空間大小。畢竟App的UI基本上來說是建立在大量的精緻的圖片上,如果這些圖片都一概使用螢幕等大小的圖片,那麼對App的效能及安裝量都是有一定的負面影響的。
對於拉伸圖片,適配ios 5及之後可以使用
1 |
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets
|
建立縮圖
如果有一張大圖,我們只想要顯示它的指定大小的縮圖內容,可以這樣做:在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, 0 );
transform = CGAffineTransformRotate(transform, M_PI_2);
break ;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0 , self.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break ;
}
switch (self.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0 );
transform = CGAffineTransformScale(transform, - 1 , 1 );
break ;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
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) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// 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);
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;
|