最近项目因为要使用到图片的缩放,制作缩放后的图片等操作,研究了下NSImage类。以及 cocoa 画图的方法。由于系统要兼容10.4。所以还是选择支持10.4的方法来实现。
NSImage 类 可以从文件,URL,NSData 获得一个Image,也可以自己画一个位图,使用NSBitmapImageRep 类。
NSImage 可以显示到NSImageView 中。你可以不改变image数据,可以直接操作 NSImageView 对象,可以缩放等操作。
由于我要制作旋转后的数据,所以要多Image进行旋转。NSImage 提供了一个方法,支持“倒转”。
- [image setScalesWhenResized:YES];
- [image setSize:psize];
- [image setFlipped:YES]; //设置倒转
前面2句是对image的缩放,设置大小NSSize=NSMakeSize{100,200},最后一句实现了倒转。这个功能不能满足我的需求。
所以我对NSImage 类进行了扩展,代码如下:
- + (NSImage *) rotateImage:(NSImage*)sourceImage byDegrees:(float)deg
- {
- NSSize srcsize= [sourceImage size];
- float srcw = srcsize.width;
- float srch= srcsize.height;
- float newdeg = 0;
- //旋转弧度
- //double ratain = ((deg/180) * PI);
- NSRect r1;
- if(0< deg && deg <=90)
- {
- r1 = NSMakeRect(0.5*(srcw -srch), 0.5*(srch-srcw), srch, srcw);
- newdeg = 90.0;
- }
- if(90< deg && deg <=180)
- {
- r1 = NSMakeRect(0, 0, srcw, srch);
- newdeg = 180.0;
- }
- if(180< deg && deg <=270)
- {
- r1 = NSMakeRect(0.5*(srcw -srch), 0.5*(srch-srcw), srch, srcw);
- newdeg = 270.0;
- }
- if(270< deg && deg <=360)
- {
- r1 = NSMakeRect(0, 0, srch, srcw);
- newdeg = 360;
- }
- //draw new image
- NSImage *rotated = [[NSImage alloc] initWithSize:[sourceImage size]];
- [rotated lockFocus];
- NSAffineTransform *transform = [NSAffineTransform transform];
- [transform translateXBy:(0.5*srcw) yBy: (0.5*srch)]; //按中心图片旋转
- [transform rotateByDegrees:newdeg]; //旋转度数,rotateByRadians:使用弧度
- [transform translateXBy:(-0.5*srcw) yBy: (-0.5*srch)];
- [transform concat];
- [[sourceImage bestRepresentationForDevice: nil] drawInRect: r1];//矩形内画图
- //[sourceImage drawInRect:r1 fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
- //[sourceImage drawAtPoint:arge/*NSZeroPoint*/ fromRect:NSMakeRect(arge.x, arge.y,ww ,wh)/*NSZeroRect*/ operation:NSCompositeCopy fraction:1.0];
- [rotated unlockFocus];
- return [rotated autorelease];
- }
原理:NSAffineTransform 类,反射转换,他可以使用一个定点,旋转图片。设置原点为定点,只要:
- NSImage *rotated = [[NSImage alloc] initWithSize:[sourceImage size]];
- [rotated lockFocus];
- NSAffineTransform *transform = [NSAffineTransform transform];
- [transform rotateByDegrees:newdeg];
- [transform concat];
- [rotated unlockFocus];
而我使用了图片对角线的交点作为定点。然后旋转一个角度,找到图片的4个顶点x,y坐标的最小值作为新坐标系的原点,得到离新坐标原点最远的x,y坐标值。得到新矩形的宽和长。
从而构造了一个新的NSRect {x,y,width,height};
这样就可以使用NSImage的draw方法画这个新的矩形,得到旋转后新的图片Image。