Rotate NSImage in an NSImageView
I didn’t want to half-implement the new tab feature in Slider – I want people to have almost as much control as if they were coding the site by hand.
This has meant I’ve had to rethink Slider’s UI many times, and I’ve had (re: couldn’t face shipping without) to implement many small features that I feel are required, from a usability standpoint.
When I decided that the user may choose to place tabs in 12 different positions, I needed to consider how this would effect the arrows and sliding animations. I came to the conclusion that if the user elects to place the tabs on the top or bottom, the arrows will be on the left and right, with the animation going right/left. If the user chooses to place tabs on the left or right, the arrows will be positioned on the top and bottom, with the animation going up/down.
Pictures make it easier:


As soon as I implemented this I realised how much of a pain it would be to copy out the arrow images, rotate them in an external program, then copy them back in. So I put some buttons next to the arrow image wells that allow the user to rotate the arrows within Slider itself.
Here is the code I used to rotate the images (thanks to Jerry Krinock and Steve Christensen and for posting this solution to the Cocoa-dev list):
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 | #import <Cocoa/Cocoa.h> @interface NSImage (Transform) /*! @brief Rotates an image around its center by a given angle in degrees and returns the new image. @details The width and height of the returned image are, respectively, the height and width of the receiver. I have not yet tested this with a non-square image. authors: Jerry Krinock and Steve Christensen */ - (NSImage*)imageRotatedByDegrees:(CGFloat)degrees ; @end #import "NSImage+Transform.h" @implementation NSImage (Transform) - (NSImage*)imageRotatedByDegrees:(CGFloat)degrees { // calculate the bounds for the rotated image NSRect imageBounds = {NSZeroPoint, [self size]}; NSBezierPath* boundsPath = [NSBezierPath bezierPathWithRect:imageBounds]; NSAffineTransform* transform = [NSAffineTransform transform]; [transform rotateByDegrees:degrees]; [boundsPath transformUsingAffineTransform:transform]; NSRect rotatedBounds = {NSZeroPoint, [boundsPath bounds].size}; NSImage* rotatedImage = [[NSImage alloc] initWithSize:rotatedBounds.size]; // center the image within the rotated bounds imageBounds.origin.x = NSMidX(rotatedBounds) - (NSWidth (imageBounds) / 2); imageBounds.origin.y = NSMidY(rotatedBounds) - (NSHeight (imageBounds) / 2); // set up the rotation transform transform = [NSAffineTransform transform]; [transform translateXBy:+(NSWidth(rotatedBounds) / 2) yBy:+ (NSHeight(rotatedBounds) / 2)]; [transform rotateByDegrees:degrees]; [transform translateXBy:-(NSWidth(rotatedBounds) / 2) yBy:- (NSHeight(rotatedBounds) / 2)]; // draw the original image, rotated, into the new image [rotatedImage lockFocus]; [transform concat]; [self drawInRect:imageBounds fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0] ; [rotatedImage unlockFocus]; return [rotatedImage autorelease]; } @end |
I had to change (from/to):
NSImage* rotatedImage = [[[NSImage alloc] initWithSize:rotatedBounds.size] autorelease];
NSImage* rotatedImage = [[NSImage alloc] initWithSize:rotatedBounds.size];
return rotatedImage;return [rotatedImage autorelease];
[transform set];
[transform concat];
For it to work flawlessly with Slider.
Thanks guys!
Like this post? Move it on along with:
Email |
delicious |
Digg |
Tweet |
Reddit |
Newsvine |
Furl |
Google |
Stumble |
HaoHao
| Trackback: |
Scroll to post title
Tile an NSImage Within an NSBezierPath
Another snippet I had to write during the great Slider rebuild.
I needed to be able to take an NSImage supplied by the user and tile it within an NSBezierPath defined by more user-set values.
The below example uses a rounded rectangle.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | NSBitmapImageRep *theImage = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:imageSize.width pixelsHigh:imageSize.height bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:0 bitsPerPixel:0]; [NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:theImage]]; //bgImage can be any NSImage NSColor *c = [NSColor colorWithPatternImage:bgImage]; [c set]; [path appendBezierPathWithRoundedRect:NSMakeRect(0, 0, imageSize.width, imageSize.height) xRadius:10.0 yRadius:10.0]; [path fill]; [NSGraphicsContext restoreGraphicsState]; |
Like this post? Move it on along with:
Email |
delicious |
Digg |
Tweet |
Reddit |
Newsvine |
Furl |
Google |
Stumble |
HaoHao
| Trackback: |
Scroll to post title
Fill a Path With A Scaled Image, Ignoring Image Proportions
While continuing to rebuild Slider’s background image features, I was forced to rewrite the code that scales an image up/down to Slider’s portal size, ignoring the image’s original proportions. The image also had to be painted within a path, as Slider may have differently shaped corners compared to the image to be scaled.
The below code accomplishes the scaling and painting of the image.
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 | //theImage = the resulting image, that will have a scaled (proportions ignored) version of "bgImage" painted onto it NSBitmapImageRep *theImage = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:imageSize.width pixelsHigh:imageSize.height bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:0 bitsPerPixel:0]; [NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:theImage]]; NSImage bg = [[NSImage alloc] initWithSize: imageSize]; //bgImage can be any NSImage NSSize originalSize = [bgImage size]; [bg lockFocus]; [bgImage drawInRect: NSMakeRect(0, 0, imageSize.width, imageSize.height) fromRect: NSMakeRect(0, 0, originalSize.width, originalSize.height) operation: NSCompositeSourceOver fraction: 1.0]; [bg unlockFocus]; NSColor *c = [NSColor colorWithPatternImage:bg]; [c set]; [path appendBezierPathWithRoundedRect:NSMakeRect(0, 0, imageSize.width, imageSize.height) xRadius:10.0 yRadius:10.0]; [aPath fill]; [NSGraphicsContext restoreGraphicsState]; |
“path” could be any NSBezierPath.
Like this post? Move it on along with:
Email |
delicious |
Digg |
Tweet |
Reddit |
Newsvine |
Furl |
Google |
Stumble |
HaoHao
| Trackback: |
Scroll to post title



























Recent Comments
Installing Jdownloader In Ubuntu
Very nice tutorial, works like charm, ty very much
cheers!
Fri, 02 Apr 2010 10:58:11 +0000
Js Kit Comments Correct Usage Of The Permalink And Path Attributes
http:www.qq8080.com.cn
Fri, 02 Apr 2010 06:49:22 +0000
Js Kit Comments Correct Usage Of The Permalink And Path Attributes
http://www.ioiojewelry.com
Mon, 29 Mar 2010 04:02:13 +0000
Super Smash Bros Brawl Oceana New Zealand Australia Friend Codes
my friend code is 3093-6756-8843 i use marth and lucario
Wed, 24 Mar 2010 02:59:40 +0000
The Mutations Of Sliders Tab Option Pane Spam
I assume you're ric?
Please see email.
Sorry for the lack of communication, been doing 12 hour days at work, got married and moved to Hong Kong.
Wed, 17 Mar 2010 10:45:45 +0000
Js Kit Comments Correct Usage Of The Permalink And Path Attributes
Sorry I can't be more help, please have a look at these links:
http://www.seomoz.org/article/bg1
http://en.wikipedia.org/wiki/Search_engine_optimization
Wed, 17 Mar 2010 10:44:34 +0000