mso*_*ohn 6 macos cocoa core-image nsimage
我正在尝试翻转使用NSImageBitmapRep表示创建的NSImage.经过一些挖掘(翻转Quicktime预览和捕获以及镜像CIImage/NSImage)后,我通过CIImage尝试了两种方法,并对这两个因子应用了-1的缩放变换.
首先使用CIImage imageByApplyingTransform:
NSBitmapImageRep *imgRep = ...
CGImageRef cgi = [imgRep CGImage];
CIImage *cii = [CIImage imageWithCGImage:cgi];
CGAffineTransform at = CGAffineTransformTranslate(CGAffineTransformMakeScale(-1, -1), 0, 0);
NSCIImageRep *ciiRep = [NSCIImageRep imageRepWithCIImage:[cii imageByApplyingTransform:at]];
NSImage *img = [[[NSImage alloc] init] autorelease];
[img addRepresentation:ciiRep];
[self.ivImage setImage:img];
Run Code Online (Sandbox Code Playgroud)
然后使用CIAffineTransform过滤器:
NSBitmapImageRep *imgRep = ...
CGImageRef cgi = [imgRep CGImage];
CIImage *cii = [CIImage imageWithCGImage:cgi];
CIFilter *f = [CIFilter filterWithName:@"CIAffineTransform"];
NSAffineTransform *t = [NSAffineTransform transform];
[t scaleXBy:1.0 yBy:1.0];
//[t translateXBy:width yBy:0];
[f setValue:t forKey:@"inputTransform"];
[f setValue:cii forKey:@"inputImage"];
CIImage *cii2 = [f valueForKey:@"outputImage"];
NSCIImageRep *ciiRep = [NSCIImageRep imageRepWithCIImage:cii2];
NSImage *img = [[[NSImage alloc] init] autorelease];
[img addRepresentation:ciiRep];
[self.ivImage setImage:img];
Run Code Online (Sandbox Code Playgroud)
两种方式都会产生空白图像.我也尝试翻译图像,以防因为-1次缩放而出现在屏幕外,但无济于事.如果我使用正值进行缩放,我可以看到正确应用了变换.
self.ivImage是一个NSImageView.我想要一个翻转的实际NSImage,因此不应该将转换应用于NSImageView.
这是32位,Lion上的Xcode 4.3.2.
你应该NSImage用一个大小来初始化你.
通过翻译展示您的尝试,因为这是正确的方式.通常,首先进行翻译然后进行缩放最容易.您的代码片段似乎有翻译尝试的残余痕迹,但它们并不正确.您在一个案例和宽度中翻译0,0,在另一个案例和宽度中翻译0.此外,在您的第二个代码段中,您缩放1,1(正),因此不会翻转.
此外,简单地将焦点锁定在适当大小的新图像上,设置变换并绘制图像代表可能更简单.避免使用所有这些东西CIImage.
NSBitmapImageRep *imgRep = ...
NSImage* img = [[[NSImage alloc] initWithSize:NSMakeSize(imgRep.pixelsWide, imgRep.pixelsHigh)] autorelease];
[img lockFocus];
NSAffineTransform* t = [NSAffineTransform transform];
[t translateXBy:imgRep.pixelsWide yBy:imgRep.pixelsHigh];
[t scaleXBy:-1 yBy:-1];
[t concat];
[imgRep drawInRect:NSMakeRect(0, 0, imgRep.pixelsWide, imgRep.pixelsHigh)];
[img unlockFocus];
Run Code Online (Sandbox Code Playgroud)
无论如何,我认为一个好主意应该是发布一个完整的功能.这是我基于Ken帖子的解决方案
- (NSImage *)flipImage:(NSImage *)image
{
NSImage *existingImage = image;
NSSize existingSize = [existingImage size];
NSSize newSize = NSMakeSize(existingSize.width, existingSize.height);
NSImage *flipedImage = [[[NSImage alloc] initWithSize:newSize] autorelease];
[flipedImage lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
NSAffineTransform *t = [NSAffineTransform transform];
[t translateXBy:existingSize.width yBy:existingSize.height];
[t scaleXBy:-1 yBy:-1];
[t concat];
[existingImage drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, newSize.width, newSize.height) operation:NSCompositeSourceOver fraction:1.0];
[flipedImage unlockFocus];
return flipedImage;
}
Run Code Online (Sandbox Code Playgroud)
Swift 的扩展,基于Alejandro Lugeno 的解决方案:
extension NSImage {
func flipped(flipHorizontally: Bool = false, flipVertically: Bool = false) -> NSImage {
let flippedImage = NSImage(size: size)
flippedImage.lockFocus()
NSGraphicsContext.current?.imageInterpolation = .high
let transform = NSAffineTransform()
transform.translateX(by: flipHorizontally ? size.width : 0, yBy: flipVertically ? size.height : 0)
transform.scaleX(by: flipHorizontally ? -1 : 1, yBy: flipVertically ? -1 : 1)
transform.concat()
draw(at: .zero, from: NSRect(origin: .zero, size: size), operation: .sourceOver, fraction: 1)
flippedImage.unlockFocus()
return flippedImage
}
}
Run Code Online (Sandbox Code Playgroud)