在Swift,Cocoa,Mac OSX中旋转NSImage

ste*_*CDP 0 cocoa image-rotation nsimage affinetransform swift

有没有一种简单的方法可以在Mac OSX应用程序中旋转NSImage?或者只是使用Swift设置从纵向到横向的方向?

我正在玩CATransform3DMakeAffineTransform,但我无法让它工作.

CATransform3DMakeAffineTransform(CGAffineTransformMakeRotation(CGFloat(M_PI) * 90/180))
Run Code Online (Sandbox Code Playgroud)

这是我第一次使用转换.所以请耐心等待我:)也许我正在采取错误的方法......

有人能帮帮我吗?

谢谢!

小智 6

感谢这个解决方案,但它对我来说并不完美.您可能已经注意到pathBounds未在任何地方使用.在我看来,必须像这样使用:

let rotatedBounds:NSRect = NSMakeRect(NSZeroPoint.x, NSZeroPoint.y , pathBounds.bounds.size.width, pathBounds.bounds.size.height )
Run Code Online (Sandbox Code Playgroud)

否则图像将旋转但裁剪为方形边界.


C-V*_*rel 5

public extension NSImage {
public func imageRotatedByDegreess(degrees:CGFloat) -> NSImage {

    var imageBounds = NSZeroRect ; imageBounds.size = self.size
    let pathBounds = NSBezierPath(rect: imageBounds)
    var transform = NSAffineTransform()
    transform.rotateByDegrees(degrees)
    pathBounds.transformUsingAffineTransform(transform)
    let rotatedBounds:NSRect = NSMakeRect(NSZeroPoint.x, NSZeroPoint.y, pathBounds.bounds.size.width, pathBounds.bounds.size.height )
    let rotatedImage = NSImage(size: 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)

    // Start a new transform
    transform = NSAffineTransform()
    // Move coordinate system to the center (since we want to rotate around the center)
    transform.translateXBy(+(NSWidth(rotatedBounds) / 2 ), yBy: +(NSHeight(rotatedBounds) / 2))
    transform.rotateByDegrees(degrees)
    // Move the coordinate system bak to normal 
    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: NSCompositingOperation.CompositeCopy, fraction: 1.0)
    rotatedImage.unlockFocus()

    return rotatedImage
}


var image = NSImage(named:"test.png")!.imageRotatedByDegreess(CGFloat(90))  //use only this values 90, 180, or 270
}
Run Code Online (Sandbox Code Playgroud)

针对Swift 3进行了更新:

public extension NSImage {
public func imageRotatedByDegreess(degrees:CGFloat) -> NSImage {

    var imageBounds = NSZeroRect ; imageBounds.size = self.size
    let pathBounds = NSBezierPath(rect: imageBounds)
    var transform = NSAffineTransform()
    transform.rotate(byDegrees: degrees)
    pathBounds.transform(using: transform as AffineTransform)
    let rotatedBounds:NSRect = NSMakeRect(NSZeroPoint.x, NSZeroPoint.y, pathBounds.bounds.size.width, pathBounds.bounds.size.height )
    let rotatedImage = NSImage(size: 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)

    // Start a new transform
    transform = NSAffineTransform()
    // Move coordinate system to the center (since we want to rotate around the center)
    transform.translateX(by: +(NSWidth(rotatedBounds) / 2 ), yBy: +(NSHeight(rotatedBounds) / 2))
    transform.rotate(byDegrees: degrees)
    // Move the coordinate system bak to normal
    transform.translateX(by: -(NSWidth(rotatedBounds) / 2 ), yBy: -(NSHeight(rotatedBounds) / 2))
    // Draw the original image, rotated, into the new image
    rotatedImage.lockFocus()
    transform.concat()
    self.draw(in: imageBounds, from: NSZeroRect, operation: NSCompositingOperation.copy, fraction: 1.0)
    rotatedImage.unlockFocus()

    return rotatedImage
    }
}

class SomeClass: NSViewController {
       var image = NSImage(named:"test.png")!.imageRotatedByDegreess(degrees: CGFloat(90))  //use only this values 90, 180, or 270
}
Run Code Online (Sandbox Code Playgroud)