LvJing 0.6.alpha.2

LvJing 0.6.alpha.2

Ke Yang 维护。



LvJing 0.6.alpha.2

  • 作者:
  • Ke Yang

LvJing

[![CI 状态](https://img.shields.io/travis/Ke Yang/LvJing.svg?style=flat)](https://travis-ci.org/Ke Yang/LvJing) 版本 许可 平台

LvJing 是一个基于 Metal 的最小图像过滤内核,它提供了可扩展的接口和协议,用于继承和组装。其架构灵感来源于 Metal by Tutorials (Caroline Begbie & Marius Horga, raywenderlich.com) 和著名的父级框架 GPUImage。LvJing 仅作为 Metal 着色器的载体,真正的数学和创造力仍然属于您。祝您玩得开心。

示例

示例包含一个视图,展示了一个由几个继承自 LvJing 过滤器的基本过滤器组成的二叉过滤树。要运行示例项目,先克隆仓库,然后在 Example 目录中运行 pod install

screenshot

编写您自己的过滤器?

让我们构建一个具有自 shaders 的伽玛过滤器。

// Gamma.metal

#include <metal_stdlib>
using namespace metal;

struct VertexOut {
   float4 position [[position]];
   float2 uv;
};

float4 adjustGamma(float4 in, float power) {
   return float4(pow(in.rgb, power), in.a);
}

vertex VertexOut vertex_main(const constant float4 *vertexArray [[buffer(0)]],
                             unsigned int vid [[vertex_id]])
{
   float4 currentVertex = vertexArray[vid];
   VertexOut out {
      .position = float4(currentVertex.x, currentVertex.y, 0, 1),
      .uv = float2(currentVertex.z, currentVertex.w)
   };
   return out;
}

fragment float4 fragment_gamma(VertexOut in [[stage_in]],
                               constant float &gamma [[buffer(0)]],
                               texture2d<float> colorTexture [[texture(0)]],
                               sampler textureSampler)
{
   float4 originColor = colorTexture.sample(textureSampler, in.uv);
   if (gamma == 1.0) {
      return originColor;
   }
   return adjustGamma(originColor, gamma);
}
// GammaFilter.swift

import MetalKit
import LvJing

public final class GammaFilter: LvJing {
   
   public var gamma: Float = 1.0
   
   public init(resolution: CGSize) {
      super.init(
         resolution: resolution,
         libraryURL: nil,
         vertexFunctionName: "vertex_main",
         fragmentFunctionName: "fragment_gamma")
   }
   
   public override func setFragmentBytesFor(encoder: MTLRenderCommandEncoder) {
      encoder.setFragmentBytes(
         &gamma,
         length: MemoryLayout<Float>.stride,
         index: 0)
   }
}

把它们连在一起?

struct BinaryTreePreview: View {
   
   @State private var originImageA: CGImage!
   
   @State private var originImageB: CGImage!
   
   @State private var inputA: InputPlaceholder!
   
   @State private var inputB: InputPlaceholder!
   
   @State private var alphaFilterA: AffineTransformFilter!
   
   @State private var alphaFilterB: GammaFilter!
   
   @State private var betaFilterA: AffineTransformFilter!
   
   @State private var betaFilterB: LuminosityFilter!
   
   @State private var terminal: SwipeTransitionFilter!

   @State private var bufferPool: CVPixelBufferPool!
   
   @State private var finalOuput: CGImage!

   func buildUp() {
      self.inputA = InputPlaceholder()
      self.inputB = InputPlaceholder()
      // alpha branch
      self.originImageA => self.inputA +> self.alphaFilterA +> self.alphaFilterB +> self.terminal
      // beta branch
      self.originImageB => self.inputB +> self.betaFilterA +> self.betaFilterB +> self.terminal
   }

   func process() {
      var buffer: CVPixelBuffer?
      let success = CVPixelBufferPoolCreatePixelBuffer(
         nil,
         self.bufferPool!,
         &buffer)
      guard success == kCVReturnSuccess else { return }

      // make filter tree propagates from its entrances;
      self.terminal.propagate()
      // draw final image into buffer;
      self.terminal => buffer!
      // do what you want with it...
   }

   func breakDown() {
      self.terminal.disconnect()
   }
}

需求

  • Swift ONLY
  • iOS 9.0+
  • macOS 10.15.5
  • Catalyst 兼容

安装

LvJing 通过 CocoaPods 提供。要安装它,只需在 Podfile 中添加以下行

pod 'LvJing'

作者

姜翼,[email protected]

许可

LvJing 按MIT许可证提供。有关更多信息,请参阅 LICENSE 文件。