2015-07-29 5 views
0

Есть ли простой способ повернуть NSImage в Mac OSX? Или просто установите ориентацию от портрета к пейзажу с помощью Swift?Поворот NSImage в Swift, Cocoa, Mac OSX

Я играю с CATransform3DMakeAffineTransform, но я не могу заставить его работать.

CATransform3DMakeAffineTransform(CGAffineTransformMakeRotation(CGFloat(M_PI) * 90/180)) 

Это первый раз, когда я работаю с преобразованиями. Поэтому, пожалуйста, будьте терпеливы со мной :) Может быть, я работаю неправильно ...

Может кто-нибудь мне помочь?

Спасибо!

ответ

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 , self.size.width, self.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 
} 

Обновление для 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 , self.size.width, self.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 
} 
+0

Спасибо очень много. Это perfekt :) – stefOCDP

+1

К сожалению, он не работает, поскольку вы не используете преобразованные «pathBounds» в любом месте (см. Ответ ниже). –

+0

это решение работает и для меня тоже, но, к сожалению, изображение с вращением плохое: / – Nininea

5

Спасибо за это решение, однако оно не работало отлично для меня. Как вы, возможно, заметили, что pathBounds нигде не используется. На мой взгляд, должен быть использован следующим образом:

let rotatedBounds:NSRect = NSMakeRect(NSZeroPoint.x, NSZeroPoint.y , pathBounds.bounds.size.width, pathBounds.bounds.size.height) 

В противном случае изображение будет поворачиваться, но обрезается до квадратной рамки.

0

Позволить IKImageView делать тяжелую работу:

import Quartz 

extension NSImage { 
    func imageRotated(by degrees: CGFloat) -> NSImage { 
     let imageRotator = IKImageView() 
     var imageRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) 
     let cgImage = self.cgImage(forProposedRect: &imageRect, context: nil, hints: nil) 
     imageRotator.setImage(cgImage, imageProperties: [:]) 
     imageRotator.rotationAngle = CGFloat(-(degrees/180) * CGFloat(M_PI)) 
     let rotatedCGImage = imageRotator.image().takeUnretainedValue() 
     return NSImage(cgImage: rotatedCGImage, size: NSSize.zero) 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^