2011-06-24 40 views
4

我試圖創建一個沿X軸,Y軸或兩者翻轉UIImage的方法。我一直在接近,但我的轉化知識不夠好,無法一路走到那裏。這裏是我到目前爲止的代碼:沿任一軸翻轉UIImage

- (UIImage *)flippedImageByAxis:(MVImageFlip)axis{ 
    UIGraphicsBeginImageContext(self.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGAffineTransform verticalFlip = CGAffineTransformMake(1, 0, 0, -1, 0, self.size.height); 
    CGAffineTransform horizFlip = CGAffineTransformMake(-1.0, 0.0, 0.0, 1.0, self.size.width, 0.0); 

    if(axis == MVImageFlipXAxis || axis == MVImageFlipXAxisAndYAxis) 
     CGContextConcatCTM(context, horizFlip); 
    if(axis == MVImageFlipYAxis || axis == MVImageFlipXAxisAndYAxis) 
     CGContextConcatCTM(context, verticalFlip); 

    CGContextDrawImage(context, CGRectMake(0.0, 0.0, self.size.width, self.size.height), [self CGImage]); 

    UIImage *flipedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return flipedImage; 
} 

這翻轉圖像,但不正確。 Y翻轉的圖像根本不會翻轉,X翻轉的圖像看起來像XY圖像應該看起來像,並且XY圖像看起來像Y圖像應該看起來像。將變革結合起來讓他們正常工作正在讓我頭痛。

MVImageFlip枚舉只是你在代碼中看到的三個。沒什麼特別的。

回答

24

我終於能想出解決辦法。以下是可能需要它的其他人的代碼。

- (UIImage *)flippedImageByAxis:(MVImageFlip)axis{ 
    UIGraphicsBeginImageContext(self.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    if(axis == MVImageFlipXAxis){ 
     // Do nothing, X is flipped normally in a Core Graphics Context 
    } else if(axis == MVImageFlipYAxis){ 
     // fix X axis 
     CGContextTranslateCTM(context, 0, self.size.height); 
     CGContextScaleCTM(context, 1.0f, -1.0f); 

     // then flip Y axis 
     CGContextTranslateCTM(context, self.size.width, 0); 
     CGContextScaleCTM(context, -1.0f, 1.0f); 
    } else if(axis == MVImageFlipXAxisAndYAxis){ 
     // just flip Y 
     CGContextTranslateCTM(context, self.size.width, 0); 
     CGContextScaleCTM(context, -1.0f, 1.0f); 
    } 

    CGContextDrawImage(context, CGRectMake(0.0, 0.0, self.size.width, self.size.height), [self CGImage]); 

    UIImage *flipedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return flipedImage; 
} 
+0

我更喜歡圖片在這種情況下的規模是這樣的:'UIGraphicsBeginImageContextWithOptions(self.size,false,self.scale);' –

9

嘗試以下操作:

UIImage* myimage = [UIImage imageNamed: @"myimage.png"]; 
myimage = [UIImage imageWithCGImage: myimage.CGImage scale: 1.0f orientation: UIImageOrientationUpMirrored]; 
+4

事實上,我發現這個片段之前,先試了一下。它沒有做任何事情,所產生的UIImage與輸入數據完全相同。我會再試一次來確定。 –

+1

只是試了一遍,仍然沒有做任何事情。很奇怪。 –

+1

這種方法似乎什麼都不做 - 謝謝Apple! – SG1

5

如果你打算只顯示圖像而不保存它,你可能不想創建第二個CGContext。這是更爲有效的使用已經加載CGImage在UIImage的,改變方向,像這樣:

- (UIImage *)flippedImageByFlippingAlongXAxis:(BOOL)flipOnX andAlongYAxis:(BOOL)flipOnY 
{ 
    UIImageOrientation currentOrientation = self.imageOrientation; 
    UIImageOrientation newOrientation = currentOrientation; 

    if (flipOnX == YES) { 
     switch (newOrientation) { 
      case UIImageOrientationUp: 
       newOrientation = UIImageOrientationDown; 
       break; 
      case UIImageOrientationDown: 
       newOrientation = UIImageOrientationUp; 
       break; 
      case UIImageOrientationUpMirrored: 
       newOrientation = UIImageOrientationDownMirrored; 
       break; 
      case UIImageOrientationDownMirrored: 
       newOrientation = UIImageOrientationUpMirrored; 
       break; 
      case UIImageOrientationLeft: 
       newOrientation = UIImageOrientationLeftMirrored; 
       break; 
      case UIImageOrientationRight: 
       newOrientation = UIImageOrientationRightMirrored; 
       break; 
      case UIImageOrientationLeftMirrored: 
       newOrientation = UIImageOrientationLeft; 
       break; 
      case UIImageOrientationRightMirrored: 
       newOrientation = UIImageOrientationRight; 
       break; 
     } 
    } 

    if (flipOnY == YES) { 
     switch (newOrientation) { 
      case UIImageOrientationUp: 
       newOrientation = UIImageOrientationUpMirrored; 
       break; 
      case UIImageOrientationDown: 
       newOrientation = UIImageOrientationDownMirrored; 
       break; 
      case UIImageOrientationUpMirrored: 
       newOrientation = UIImageOrientationUp; 
       break; 
      case UIImageOrientationDownMirrored: 
       newOrientation = UIImageOrientationDown; 
       break; 
      case UIImageOrientationLeft: 
       newOrientation = UIImageOrientationRight; 
       break; 
      case UIImageOrientationRight: 
       newOrientation = UIImageOrientationLeft; 
       break; 
      case UIImageOrientationLeftMirrored: 
       newOrientation = UIImageOrientationRightMirrored; 
       break; 
      case UIImageOrientationRightMirrored: 
       newOrientation = UIImageOrientationLeftMirrored; 
       break; 
     } 
    } 

    return [UIImage imageWithCGImage:self.CGImage scale:self.scale orientation:newOrientation]; 
} 

當你開始一個新的CGContext上,並使用CGContextDrawImage做翻轉,你分配的內存的另一個塊以不同的順序保存相同的字節。通過更改UIImage方向,您可以避免另一次分配。使用相同的圖像數據,只是以不同的方向繪製。

+0

這是舊的,但我想我會評論。我其實確實需要將圖像保存在我的特定問題中。無論哪種方式,這都是很好的建議,如果圖像僅用於顯示,則效率更高。 –

+0

我喜歡這個答案,我喜歡重複使用CGContext,因爲我只顯示圖片。現在或現在它是不正確的。更改(以Swift符號)'.Up'到'.Down'或'.LeftMirrored'到'.RightMirrored'實際上是180度旋轉,因此每個開關中的4個情況不會進行反射。爲了在上面的例子中解決它,你只需要確保,對於每種情況,你總是添加或刪除'鏡像'。我會在迅速添加另一個答案完整 – fresidue

1

這僅僅是一個稍微修復並由@ultramiraculous'更新爲舊的答案的Swift'版本。以防萬一它有助於某人。

垂直翻轉(超過x軸反射):

func flipV(im:UIImage)->UIImage { 
    var newOrient:UIImageOrientation 
    switch im.imageOrientation { 
    case .Up: 
     newOrient = .DownMirrored 
    case .UpMirrored: 
     newOrient = .Down 
    case .Down: 
     newOrient = .UpMirrored 
    case .DownMirrored: 
     newOrient = .Up 
    case .Left: 
     newOrient = .LeftMirrored 
    case .LeftMirrored: 
     newOrient = .Left 
    case .Right: 
     newOrient = .RightMirrored 
    case .RightMirrored: 
     newOrient = .Right 
    } 
    return UIImage(CGImage: im.CGImage, scale: im.scale, orientation: newOrient) 
} 

水平翻轉(超過y軸反射)

func flipH(im:UIImage)->UIImage { 
    var newOrient:UIImageOrientation 
    switch im.imageOrientation { 
    case .Up: 
     newOrient = .UpMirrored 
    case .UpMirrored: 
     newOrient = .Up 
    case .Down: 
     newOrient = .DownMirrored 
    case .DownMirrored: 
     newOrient = .Down 
    case .Left: 
     newOrient = .RightMirrored 
    case .LeftMirrored: 
     newOrient = .Right 
    case .Right: 
     newOrient = .LeftMirrored 
    case .RightMirrored: 
     newOrient = .Left 
    } 
    return UIImage(CGImage: im.CGImage, scale: im.scale, orientation: newOrient) 
} 
-1

夫特3版本:

func flipV(im:UIImage)->UIImage { 
     var newOrient:UIImageOrientation 
     switch im.imageOrientation { 
     case .up: 
      newOrient = .downMirrored 
     case .upMirrored: 
      newOrient = .down 
     case .down: 
      newOrient = .upMirrored 
     case .downMirrored: 
      newOrient = .up 
     case .left: 
      newOrient = .leftMirrored 
     case .leftMirrored: 
      newOrient = .left 
     case .right: 
      newOrient = .rightMirrored 
     case .rightMirrored: 
      newOrient = .right 
     } 
     return UIImage(cgImage: im.cgImage!, scale: im.scale, orientation: newOrient) 
    } 

    func flipH(im:UIImage)->UIImage { 
     var newOrient:UIImageOrientation 
     switch im.imageOrientation { 
     case .up: 
      newOrient = .upMirrored 
     case .upMirrored: 
      newOrient = .up 
     case .down: 
      newOrient = .downMirrored 
     case .downMirrored: 
      newOrient = .down 
     case .left: 
      newOrient = .rightMirrored 
     case .leftMirrored: 
      newOrient = .right 
     case .right: 
      newOrient = .leftMirrored 
     case .rightMirrored: 
      newOrient = .left 
     } 
     return UIImage(cgImage: im.cgImage!, scale: im.scale, orientation: newOrient) 
    } 
+2

請不要提供代碼的答案。你應該詳細說明你的方法。這有助於其他用戶更好地理解您的解決方案。 – QueryLars