【问题标题】:Xcode: compositing with alpha using core imageXcode:使用核心图像与 alpha 合成
【发布时间】:2013-01-06 12:02:04
【问题描述】:

我想创建一个 CoreImage 过滤器链,并能够通过将其单独的效果与 alpha 或不透明度设置组合来控制链中每个过滤器的“强度”,但我没有看到一种方法在文档中与 alpha 或 opacity 复合。

我想我可以跳出核心图像过滤器链并与核心图形上下文合成。

【问题讨论】:

    标签: ios image core-graphics core-image


    【解决方案1】:

    mrwalker 提供了一个很好的答案,我将其转换为 Swift。

    斯威夫特 5

    let sourceImage: CIImage = ...
    
    // This is where I get the overlayImage, and intensity is alpha, used later
    guard let ciFilter = LUTBuilder.getCIFilter(from: filter.filter), let intensity = filter.intensity else { return CIImage() }
    ciFilter.setValue(sourceImage.clampedToExtent(), forKey: kCIInputImageKey)
    
    let overlayImage = ciFilter.outputImage!.cropped(to: sourceImage.extent)
    
    let alpha = CGFloat(intensity)
    let rgba = [0.0, 0.0, 0.0, alpha]
    
    guard
        let colorMatrix = CIFilter(name: "CIColorMatrix"),
        let composite = CIFilter(name: "CISourceOverCompositing")
    else { return CIImage() }
    
    colorMatrix.setDefaults()
    colorMatrix.setValue(overlayImage, forKey: kCIInputImageKey)
    colorMatrix.setValue(CIVector(values: rgba, count: 4), forKey: "inputAVector")
    
    composite.setDefaults()
    composite.setValue(colorMatrix.outputImage, forKey: kCIInputImageKey)
    composite.setValue(sourceImage, forKey: kCIInputBackgroundImageKey)
    
    return composite.outputImage ?? CIImage()
    

    【讨论】:

      【解决方案2】:

      CIColorMatrix 过滤器可用于更改 CIImage 的 alpha 分量,然后您可以将其合成到背景图像上:

      CIImage *overlayImage = … // from file, CGImage etc
      CIImage *backgroundImage = … // likewise
      
      CGFloat alpha = 0.5;
      CGFloat rgba[4] = {0.0, 0.0, 0.0, alpha};
      CIFilter *colorMatrix = [CIFilter filterWithName:@"CIColorMatrix"];
      [colorMatrix setDefaults];
      [colorMatrix setValue:overlayImage forKey: kCIInputImageKey];
      [colorMatrix setValue:[CIVector vectorWithValues:rgba count:4] forKey:@"inputAVector"];
      
      CIFilter *composite = [CIFilter filterWithName:@"CISourceOverCompositing"];
      [composite setDefaults];
      [composite setValue:colorMatrix.outputImage forKey: kCIInputImageKey];
      [composite setValue:backgroundImage forKey: kCIInputBackgroundImageKey];
      
      UIImage *blendedImage = [UIImage imageWithCIImage:composite.outputImage];
      

      【讨论】:

        【解决方案3】:

        最后是这样的。此答案的代码:https://stackoverflow.com/a/3188761/1408546

        UIImage *bottomImage = inputImage;
        UIImage *image = filterOutput;
        CGSize newSize = CGSizeMake(inputImage.size.width, inputImage.size.height);
        UIGraphicsBeginImageContext( newSize );
        [bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
        [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:_opacity];
        UIImage *blendedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        

        【讨论】:

        • 如果您在 Core Image 和 Core Graphics 之间切换,您将在使用 GPU 和 CPU 进行绘图之间切换。这样做会产生性能成本。一般来说,如果您尽可能多地使用 GPU(并尽量减少切换),您将在这些类型的绘图/合成任务中获得更好的性能。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-04
        相关资源
        最近更新 更多