【问题标题】:CIColorMap doesn't apply gradient uniformly to input imageCIColorMap 不会将渐变均匀地应用于输入图像
【发布时间】:2015-07-11 20:14:25
【问题描述】:

我通过加载附加的蓝到红渐变图像创建了一个 CIColorMap 过滤器。

然后我尝试将其应用于灰度输入图像,它只是从黑色到白色的线性渐变。

当我在 CIContext 中绘制 CIColorMap 的输出图像时,其目的是将黑色渲染为深蓝色,将白色渲染为深红色,将中灰色渲染为白色。然而实际结果是这样的:

如您所见,中间灰色实际上映射为浅蓝色,而不是我预期的白色。

以下是源代码。鉴于文档非常稀缺,我想知道我是否一直在错误地使用 CIColorMap。

// Interface file
#import <Cocoa/Cocoa.h>
@interface ColorMapView : NSView
@end

// Implementation file
#import <QuartzCore/QuartzCore.h>
#import "ColorMapView.h"

static size_t imageWitdh = 512;
static size_t imageHeight = 125;

@implementation ColorMapView {
    CIImage *m_backgroundImage;
    CIImage *m_colorMapGradient;
    CIFilter *m_colorMapFilter;
    CIContext *m_ciContext;
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        [self initBackgroundImage];
        [self initColorMapGradient];
    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    if (!m_ciContext)  {
        m_ciContext = [CIContext contextWithCGContext:[NSGraphicsContext currentContext].graphicsPort options:nil];
    }

    CGFloat x = (self.bounds.size.width - imageWitdh) / 2;
    CGFloat y = (self.bounds.size.height - imageHeight) / 2;

    // Drawing code here.
    [m_colorMapFilter setValue:m_backgroundImage forKey:kCIInputImageKey];
    [m_ciContext drawImage:[m_colorMapFilter valueForKey:kCIOutputImageKey] inRect:CGRectMake(x, y, imageWitdh, imageHeight) fromRect:m_backgroundImage.extent];
}

- (void)initBackgroundImage {
     CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
    CGContextRef context = CGBitmapContextCreate(NULL, imageWitdh, imageHeight, 8, imageWitdh, colorSpace, (CGBitmapInfo)kCGImageAlphaNone);
    CGFloat locations[2] = {0.0, 1.0};
    CGFloat components[4] = {0.0, 1.0, 1.0, 1.0};
    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2);
    CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(imageWitdh, 0), NO);
    CGImageRef gradientImage = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    CGGradientRelease(gradient);
    CGColorSpaceRelease(colorSpace);
    m_backgroundImage = [CIImage imageWithCGImage:gradientImage];
    CGImageRelease(gradientImage);
}

- (void)initColorMapGradient {
    NSString* imagePath = [[NSBundle mainBundle] pathForResource:@"blue_red_scale_gradient" ofType:@"png"];
    CGDataProviderRef dataProvider = CGDataProviderCreateWithFilename(imagePath.UTF8String);
    CGImageRef image = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO, kCGRenderingIntentDefault);
    m_colorMapGradient = [CIImage imageWithCGImage:image];
    CGImageRelease(image);
    m_colorMapFilter = [CIFilter filterWithName:@"CIColorMap"];
    [m_colorMapFilter setValue:m_colorMapGradient forKey:@"inputGradientImage"];
}

@end

【问题讨论】:

  • 输入梯度真的应该是black -&gt; blue -&gt; white -&gt; yellow -&gt; red -&gt; black吗?绿色呢? :) 我希望 Apple 提供一个“默认”颜色映射,而不是 FunHouse 演示中那个奇怪的颜色映射,这样我们就可以知道要修改哪些颜色。
  • 渐变由我们的 UI 设计师针对应用确定。关键是我希望看到白色在输出图像中居中。换句话说,在这种特殊情况下,输出图像应该看起来与梯度图像本身相同。

标签: cocoa core-image


【解决方案1】:

这似乎与色彩管理问题有关。如果我在创建 CIContext 对象时将 kCIContextWorkingColorSpace 设置为 NSNull,我会得到预期的结果。

if (!m_ciContext)  {
    NSDictionary *options = @{kCIContextWorkingColorSpace : [NSNull null]};
    m_ciContext = [CIContext contextWithCGContext:[NSGraphicsContext currentContext].graphicsPort options:options];
}

【讨论】:

  • 哇,很棒的发现。谢谢!
猜你喜欢
  • 2020-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 2011-01-29
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多