2011-06-24 22 views
4

UIImageをX軸、Y軸、またはその両方に沿って反転させるメソッドを作成しようとしています。私は近くに近づいていますが、私の変革の知識はそれだけで十分ではありません。ここに私が今まで持っているコードはあります:どちらかの軸に沿って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列挙型は、コードに表示されている3つの列挙型です。特にない。

答えて

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

Iが実際に見出され前にこのスニペットとそれを最初に試してみました。それは何もしなかった、結果のUIImagesは入力とまったく同じだった。もう一度試してみるよ。 –

+1

もう一度試してみましたが、何もしません。非常に奇妙な。 –

+1

この方法は何もしないようです - Appleに感謝します! – SG1

5

イメージを表示して保存しない場合は、2番目のCGContextを作成したくない場合があります。それはちょうどそうのような方向性をUIImageに既にロードされてCGImageを使用し、変更することがはるかに効率的です:

- (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を再利用するのが好きです。今のところそれは間違っています。 '.Down'または' .LeftMirrored'から '.RightMirrored'への' .Up'を実際には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

関連する問題