IOS应用开发-图片处理(拉伸图片 创建缩略图 解决图片旋转的问题 图片编码及上传 将图片写入磁盘)

来源:互联网 发布:如何开展网络推广工作 编辑:程序博客网 时间:2024/06/03 15:16

在做项目时我们经常要对图片进行一些处理,以达到性能优化或满足需求。常见的情形有以下几种

//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;
0 0