Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
shima11 committed Jun 10, 2024
1 parent 06c2aa0 commit 924878e
Showing 1 changed file with 106 additions and 18 deletions.
124 changes: 106 additions & 18 deletions Dev/Sources/SwiftUIDemo/DemoFilterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,89 @@ struct DemoFilterView: View {
}
}


class MotionBlurFilter: CIFilter {
var inputImage: CIImage?
var inputDirection: CIVector = CIVector(x: 1, y: 0)

let kernel = CIKernel(source:
"""
kernel vec4 motionBlur(sampler image, vec2 direction) {
vec2 dc = destCoord();
vec4 color = vec4(0.0);
int samples = 20;
for (int i = -samples; i <= samples; i++) {
vec2 offset = direction * (10 * float(i) / float(samples));
color += sample(image, samplerCoord(dc + offset));
}
return color / float(samples * 2 + 1);
}
"""
)

override var outputImage: CIImage? {
guard let inputImage = inputImage, let kernel = kernel else { return nil }
let arguments = [inputImage, inputDirection] as [Any]
return kernel.apply(extent: inputImage.extent, roiCallback: { _, rect in rect }, arguments: arguments)
}
}

struct ChromaticAberrationFilter: Filtering {

let kernel = CIKernel(source:
"""
kernel vec4 motionBlur(sampler image, vec2 size, float sampleCount, float start, float blur) {
int sampleCountInt = int(floor(sampleCount));
vec4 accumulator = vec4(0.0);
vec2 dc = destCoord();
float normalisedValue = length(((dc / size) - 0.5) * 2.0);
float strength = clamp((normalisedValue - start) * (1.0 / (1.0 - start)), 0.0, 1.0);
vec2 vector = normalize((dc - (size / 2.0)) / size);
vec2 velocity = vector * strength * blur;
vec2 redOffset = -vector * strength * (blur * 1.0);
vec2 greenOffset = -vector * strength * (blur * 1.5);
vec2 blueOffset = -vector * strength * (blur * 2.0);
for (int i=0; i < sampleCountInt; i++) {
accumulator.r += sample(image, samplerTransform(image, dc + redOffset)).r;
redOffset -= velocity / sampleCount;
accumulator.g += sample(image, samplerTransform(image, dc + greenOffset)).g;
greenOffset -= velocity / sampleCount;
accumulator.b += sample(image, samplerTransform(image, dc + blueOffset)).b;
blueOffset -= velocity / sampleCount;
}
return vec4(vec3(accumulator / float(sampleCountInt)), 1.0);
}
""")!

func apply(to image: CIImage, sourceImage: CIImage) -> CIImage {

let args = [image,
CIVector(x: image.extent.width, y: image.extent.height),
20,
0.2,
20,
] as [Any]

return kernel.apply(
extent: image.extent,
roiCallback: { _, rect in
rect
},
arguments: args
)!
}
}

let invertFilter: InvertFilter = .init()
let grayscaleFilter: GrayscaleFilter = .init()
let chromaticFilter: ChromaticAberrationFilter = .init()

@StateObject var editingStack: EditingStack
@State var invertToggle: Bool = false
@State var grascaleToggle: Bool = false
@State var grayscaleToggle: Bool = false
@State var chromaticToggle: Bool = false

@State var resultImage: ResultImage?

init(
editingStack: @escaping () -> EditingStack
Expand All @@ -52,33 +129,44 @@ struct DemoFilterView: View {

ViewHost(instantiated: ImagePreviewView(editingStack: editingStack))

SwiftUICropView(editingStack: editingStack)
.clipped()

VStack {
Toggle("Invert", isOn: $invertToggle)
.onChange(of: invertToggle) { newValue in
editingStack.set(filters: {
$0.additionalFilters = [
grascaleToggle ? grayscaleFilter.asAny() : nil,
invertToggle ? invertFilter.asAny() : nil,
].compactMap({ $0 })
})
}
Toggle("Grayscale", isOn: $grayscaleToggle)
Toggle("Chromatic", isOn: $chromaticToggle)
}
.onChange(of: [invertToggle, grayscaleToggle, chromaticToggle], perform: { _ in
editingStack.set(filters: {
$0.additionalFilters = [
grayscaleToggle ? grayscaleFilter.asAny() : nil,
invertToggle ? invertFilter.asAny() : nil,
chromaticToggle ? chromaticFilter.asAny() : nil,
].compactMap({ $0 })
})
})
.padding()

Toggle("Grayscale", isOn: $grascaleToggle)
.onChange(of: grascaleToggle) { newValue in
editingStack.set(filters: {
$0.additionalFilters = [
grascaleToggle ? grayscaleFilter.asAny() : nil,
invertToggle ? invertFilter.asAny() : nil,
].compactMap({ $0 })
})
Button("Done") {
try! editingStack.makeRenderer().render { result in
switch result {
case let .success(rendered):
self.resultImage = .init(cgImage: rendered.cgImage)
case let .failure(error):
print(error)
}
}
}
.padding()

}
.onAppear {
editingStack.start()
}
.sheet(item: $resultImage) {
RenderedResultView(result: $0)
}

}

}
Expand Down

0 comments on commit 924878e

Please sign in to comment.