Hi,
I’ve been looking for simple method to rotate a picture object by angle without using 3rd party plugins.
Since I am developing only under Mac OS X I checked the MacOS Lib first & the Mac Developer page for examples and made up
a method to rotate a picture object with a given angle which I want to share in case somebody else may need it too.
I currently know 3 ways to rotate a picture:
1.) MacOS - make a canvas and set your picture as backdrop and use:
declare sub rotateByAngle lib Cocoa selector “rotateByAngle:” (obj_id as Ptr, angle as Single)
2.) MacOS - see my method below
3.) ALL - use Xojo built in PixmapShape class
I checked+compared the performance for Option 2 & 3, resulting in an overall performance of 0.27ms for 2 and about 4.5ms for 3
with 100 iterations.
Function Rotate( picObj as Picture, angle as single) as Picture
const M_PI = 3.14159265
const kCGImageAlphaPremultipliedFirst = 2
soft declare sub CFRelease lib CarbonLib ( obj as ptr )
soft declare sub CGContextTranslateCTM lib CarbonLib (context as Ptr, tx as Single, ty as Single)
soft declare sub CGContextRotateCTM lib CarbonLib (context as Ptr, angle as Single)
soft Declare Sub CGContextDrawImage Lib CarbonLib (context As Ptr, rect As CGRect, image As Ptr)
soft declare function CGBitmapContextCreateImage lib CarbonLib (context as Ptr) as Ptr
soft declare function CGBitmapContextCreate lib CarbonLib (data as Ptr, width as Integer, height as Integer, bitsPerComponent as Integer, bytesPerRow as Integer, colorspace as Ptr, bitmap as UInt32) as Ptr
soft declare function CGColorSpaceCreateWithName lib CarbonLib (name as CFStringRef) as Ptr
soft declare sub CGContextClearRect lib CarbonLib (context as Ptr, rect as CGRect)
dim w as integer = picObj.Width
dim h as integer = picObj.Height
dim p as Picture
// pass nil & 0 to have OS calculate the buffer itself
dim cntx as Ptr = CGBitmapContextCreate( nil, w, h, 8, 0, CGColorspaceCreateWithName("kCGColorSpaceGenericRGB"), kCGImageAlphaPremultipliedFirst )
if cntx <> nil then
CGContextTranslateCTM cntx, w/2.0, h/2.0
CGContextRotateCTM cntx, angle /180.0 * M_PI
CGContextTranslateCTM cntx, -(w/2.0), -(h/2.0)
dim cgImageRef as Ptr = picObj.CopyOSHandle(Picture.HandleType.MacCGImage)
if cgImageRef <> nil then
dim r as CGRect
r.width = w
r.height = h
CGContextDrawImage( cntx, r, cgImageRef )
CFRelease( cgImageRef )
p = New Picture ( w, h )
dim newCntxRef as Ptr = CGBitmapContextCreateImage( cntx )
CGContextDrawImage( Ptr( p.Graphics.Handle( Graphics.HandleTypeCGContextRef ) ), r, newCntxRef )
CFRelease ( newCntxRef )
end if
CFRelease( cntx )
end if
return p
Please comment/discuss or let me know your thoughts. Maybe someone else has a different solution with less overhead or so.
If you need more comments what the code, please let me know.