IOS應用開發-圖片處理 – iPhone手機開發技術文章 iPhone軟體開發教學課程

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

拉伸圖片

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

對於拉伸圖片,適配ios 5及之後可以使用

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets

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

創建縮略圖

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

- (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系統下看到的圖片會發生旋轉的現象,那是因為我們沒有通過圖片的旋轉屬性修改圖片轉向。可以用下面的方法解決這個問題:

@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對象

#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:接口寫入

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

發佈留言