Pie*_*ard 28 cocoa objective-c core-image
我有一个灰度图像,我想用它来绘制Cocoa控件.图像具有不同级别的灰度.在最黑暗的地方,我希望它能画出最暗的指定色调.我希望它在源图像为白色时是透明的.
基本上,我想重现iPhone上UINavigationBar中看到的tintColor的行为.
到目前为止,我已经探索了几个选项:
使用SourceOver合成在灰度图像上绘制色调颜色 - >这需要非不透明的色调 - >结果比期望的要暗得多
使用CIMultiplyCompositing CIFilter为图像着色 - >我不能[CIImage drawAtPoint:fromRect:operation:fraction:]只绘制部分图像.同样适用于NSImage - >我偶尔会碰到一些我无法理解的崩溃
将灰度图像转换为蒙版.即黑色应该是不透明的.白色应该是透明的.灰色应具有中间alpha值. - >这似乎是最好的解决方案 - >尽我所能,我无法做到这一点.
blu*_*boo 40
上述解决方案对我不起作用.但这个更容易的解决方案对我来说非常有用
- (NSImage *)imageTintedWithColor:(NSColor *)tint
{
NSImage *image = [self copy];
if (tint) {
[image lockFocus];
[tint set];
NSRect imageRect = {NSZeroPoint, [image size]};
NSRectFillUsingOperation(imageRect, NSCompositeSourceAtop);
[image unlockFocus];
}
return image;
}
Run Code Online (Sandbox Code Playgroud)
Jef*_*Hay 13
快速实现bluebamboo的答案:
func tintedImage(_ image: NSImage, tint: NSColor) -> NSImage {
guard let tinted = image.copy() as? NSImage else { return image }
tinted.lockFocus()
tint.set()
let imageRect = NSRect(origin: NSZeroPoint, size: image.size)
NSRectFillUsingOperation(imageRect, .sourceAtop)
tinted.unlockFocus()
return tinted
}
Run Code Online (Sandbox Code Playgroud)
- (NSImage *)imageTintedWithColor:(NSColor *)tint
{
if (tint != nil) {
NSSize size = [self size];
NSRect bounds = { NSZeroPoint, size };
NSImage *tintedImage = [[NSImage alloc] initWithSize:size];
[tintedImage lockFocus];
CIFilter *colorGenerator = [CIFilter filterWithName:@"CIConstantColorGenerator"];
CIColor *color = [[[CIColor alloc] initWithColor:tint] autorelease];
[colorGenerator setValue:color forKey:@"inputColor"];
CIFilter *monochromeFilter = [CIFilter filterWithName:@"CIColorMonochrome"];
CIImage *baseImage = [CIImage imageWithData:[self TIFFRepresentation]];
[monochromeFilter setValue:baseImage forKey:@"inputImage"];
[monochromeFilter setValue:[CIColor colorWithRed:0.75 green:0.75 blue:0.75] forKey:@"inputColor"];
[monochromeFilter setValue:[NSNumber numberWithFloat:1.0] forKey:@"inputIntensity"];
CIFilter *compositingFilter = [CIFilter filterWithName:@"CIMultiplyCompositing"];
[compositingFilter setValue:[colorGenerator valueForKey:@"outputImage"] forKey:@"inputImage"];
[compositingFilter setValue:[monochromeFilter valueForKey:@"outputImage"] forKey:@"inputBackgroundImage"];
CIImage *outputImage = [compositingFilter valueForKey:@"outputImage"];
[outputImage drawAtPoint:NSZeroPoint
fromRect:bounds
operation:NSCompositeCopy
fraction:1.0];
[tintedImage unlockFocus];
return [tintedImage autorelease];
}
else {
return [[self copy] autorelease];
}
}
- (NSImage*)imageCroppedToRect:(NSRect)rect
{
NSPoint point = { -rect.origin.x, -rect.origin.y };
NSImage *croppedImage = [[NSImage alloc] initWithSize:rect.size];
[croppedImage lockFocus];
{
[self compositeToPoint:point operation:NSCompositeCopy];
}
[croppedImage unlockFocus];
return [croppedImage autorelease];
}
Run Code Online (Sandbox Code Playgroud)
我想用具有 alpha 的色调颜色为图像着色,而不会看到图像的原始颜色显示出来。您可以这样做:
extension NSImage {
func tinting(with tintColor: NSColor) -> NSImage {
guard let cgImage = self.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return self }
return NSImage(size: size, flipped: false) { bounds in
guard let context = NSGraphicsContext.current?.cgContext else { return false }
tintColor.set()
context.clip(to: bounds, mask: cgImage)
context.fill(bounds)
return true
}
}
}
Run Code Online (Sandbox Code Playgroud)