LvJing
[](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
。
编写您自己的过滤器?
让我们构建一个具有自 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'
作者
许可
LvJing 按MIT许可证提供。有关更多信息,请参阅 LICENSE 文件。