在做项目时我们经常要对图片进行一些处理,以达到性能优化或满足需求。常见的情形有以下几种
拉伸图片
项目中使用的图片素材如果能通过拉伸获得就尽量这样去做。这样做有两个显而易见的好处,一是能够减少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;
|