【发布时间】:2011-03-08 22:35:46
【问题描述】:
我想弄清楚是否有任何方法可以镜像图像。例如,拍一张某人的脸,然后将其切成两半,并展示他们的脸在每侧镜像后的样子。 CGAffineTransform 函数中似乎没有这样的技巧。请图形专家帮忙!!!
【问题讨论】:
标签: iphone uiimage core-graphics uiimagepickercontroller
我想弄清楚是否有任何方法可以镜像图像。例如,拍一张某人的脸,然后将其切成两半,并展示他们的脸在每侧镜像后的样子。 CGAffineTransform 函数中似乎没有这样的技巧。请图形专家帮忙!!!
【问题讨论】:
标签: iphone uiimage core-graphics uiimagepickercontroller
这里的基本“技巧”是使用关于 X 或 Y 轴的缩放变换,系数为 -1。例如,您可以使用它来创建“绕水平轴翻转”变换:
CGAffineTransform transform = CGAffineTransformScale(transform, -1, 1);
然后您可以在UIImageView 上设置transform 属性来翻转指定的图像,或者将其与另一个变换连接以实现更复杂的效果。要获得您描述的确切效果,您可能需要编写一些自定义绘图代码来将原始图像绘制到上下文中,然后将翻转的一半覆盖在它上面。这在 Core Graphics 中相对简单。
【讨论】:
myImageView.transform = CGAffineTransformMakeScale(-1, 1);
如果你只打算支持 4.0+
UIImageOrientation flippedOrientation = UIImageOrientationUpMirrored;
switch (image.imageOrientation) {
case UIImageOrientationUp: break;
case UIImageOrientationDown: flippedOrientation = UIImageOrientationDownMirrored; break;
// ...
}
UIImage * flippedImage = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:flippedOrientation];
【讨论】:
你可能会想,为什么要为长得离谱的 switch 语句烦恼呢?
? UIImage *flip = [UIImage imageWithCGImage:image.CGImage
? scale:image.scale
? orientation:(image.imageOrientation + 4) % 8];
如果你看一下枚举,你会发现模算术可以做到:
typedef NS_ENUM(NSInteger, UIImageOrientation) {
UIImageOrientationUp, // default orientation
UIImageOrientationDown, // 180 deg rotation
UIImageOrientationLeft, // 90 deg CCW
UIImageOrientationRight, // 90 deg CW
UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip
UIImageOrientationDownMirrored, // horizontal flip
UIImageOrientationLeftMirrored, // vertical flip
UIImageOrientationRightMirrored, // vertical flip
};
但是这段代码太聪明了。您应该编写一个带有显式 switch 语句的函数。例如
UIImageOrientation mirroredImageOrientation(UIImageOrientation orientation) {
switch(orientation) {
case UIImageOrientationUp: return UIImageOrientationUpMirrored;
case UIImageOrientationDown: return UIImageOrientationDownMirrored;
case UIImageOrientationLeft: return UIImageOrientationLeftMirrored;
case UIImageOrientationRight: return UIImageOrientationRightMirrored;
case UIImageOrientationUpMirrored: return UIImageOrientationUp;
case UIImageOrientationDownMirrored: return UIImageOrientationDown;
case UIImageOrientationLeftMirrored: return UIImageOrientationLeft;
case UIImageOrientationRightMirrored: return UIImageOrientationRight;
default: return orientation;
}
}
并像这样使用函数:
UIImage *flip = [UIImage imageWithCGImage:image.CGImage
scale:image.scale
orientation:mirroredImageOrientation(image.imageOrientation)];
我添加了问号来表示有问题的、有异味的代码。类似于The Practice of Programming
【讨论】:
以上没有答案,请回答问题的一部分,即镜像一半图像而不是翻转整个图像。混合解决方案会产生以下示例函数,您可以将其用作 UIImage+Mirroring 等类别:
(UIImage *) horizontalMirror {
UIImageOrientation flippedOrientation = UIImageOrientationUpMirrored;
switch (self.imageOrientation) {
case UIImageOrientationUp: break;
case UIImageOrientationDown: flippedOrientation = UIImageOrientationDownMirrored; break;
}
UIImage * flippedImage = [UIImage imageWithCGImage:self.CGImage scale:1.0 orientation:flippedOrientation];
CGImageRef inImage = self.CGImage;
CGContextRef ctx = CGBitmapContextCreate(NULL,
CGImageGetWidth(inImage),
CGImageGetHeight(inImage),
CGImageGetBitsPerComponent(inImage),
CGImageGetBytesPerRow(inImage),
CGImageGetColorSpace(inImage),
CGImageGetBitmapInfo(inImage)
);
CGRect cropRect = CGRectMake(flippedImage.size.width/2, 0, flippedImage.size.width/2, flippedImage.size.height);
CGImageRef TheOtherHalf = CGImageCreateWithImageInRect(flippedImage.CGImage, cropRect);
CGContextDrawImage(ctx, CGRectMake(0, 0, CGImageGetWidth(inImage), CGImageGetHeight(inImage)), inImage);
CGAffineTransform transform = CGAffineTransformMakeTranslation(flippedImage.size.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
CGContextConcatCTM(ctx, transform);
CGContextDrawImage(ctx, cropRect, TheOtherHalf);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
CGContextRelease(ctx);
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return finalImage;
}
【讨论】:
使用起来更简单:
UIImage(assetIdentifier: .myIcon)?.withHorizontallyFlippedOrientation()
【讨论】:
您可以将以下代码用于 Swift 4.0
func didTakePicture(_ real_image: UIImage) {
//suppose real_image = :)
var flipped_image = UIImage(CGImage: real_image.CGImage!, scale: real_image.scale, orientation: .leftMirrored)
// flipped_image is (:
}
【讨论】: