は、ここスウィフト3からいくつかのスウィフト4コード(そのままです両方ともビルドして実行します)。私はあなたの問題がどこにあるか見ていないので、これがあなたを助けないなら、コメントして、私はそれを削除します。 (それがヘルプがない場合、私はより具体的には私の答えを編集しましょう!)
最初CIFilter
はUILabel
内のテキストをもとに、「テキストマスク」を作成するCIColorInvert
とCIHeightFieldFromMask
を使用しています。またoverrides
プロパティはCIFilter
です。第2のCIFilter
は、実際には、CIImage
としてCIImage
をCIKernel
の周りの「ラッパー」とし、inputMask
というマスク(最初のフィルタのマスク)と、最初のものと同じようにoutputImage
を上書きします。
このコードのほぼすべては、Simon GladmanによってCore Image for Swiftから取り除かれました。現在、iBookとして無料で提供されています。この本はSwift 2で書かれていましたが、Core Imageを扱うための貴重なリソースとなっています。
(サイドノート:。。!本は、私が透かしとして、既存のアプリにこれを適応させるに取り組んでいたとして、私は物事を分割し、このすべてを兼ね備えた、私は別のルートを行くことになった)
マスク。迅速
public class Mask: CIFilter {
public var inputExtent:CGRect?
var inputRadius: Float = 15 {
didSet {
if oldValue != inputRadius {
refractingImage = nil
}
}
}
private var refractingImage: CIImage?
private var rawTextImage: CIImage?
override public var outputImage: CIImage! {
if refractingImage == nil {
generateRefractingImage()
}
let mask = refractingImage?.applyingFilter("CIColorInvert", parameters: [:])
return mask
}
func generateRefractingImage() {
let label = UILabel(frame: inputExtent!)
label.text = "grand canyon"
label.font = UIFont.boldSystemFont(ofSize: 300)
label.adjustsFontSizeToFitWidth = true
label.textColor = UIColor.white
UIGraphicsBeginImageContextWithOptions(
CGSize(width: label.frame.width,
height: label.frame.height), true, 1)
label.layer.render(in: UIGraphicsGetCurrentContext()!)
let textImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
rawTextImage = CIImage(image: textImage!)!
refractingImage = CIFilter(name: "CIHeightFieldFromMask",
withInputParameters: [
kCIInputRadiusKey: inputRadius,
kCIInputImageKey: rawTextImage!])?.outputImage?
.cropped(to: inputExtent!)
}
}
Refraction.swift
public class Refraction: CIFilter {
public var inputImage: CIImage?
public var inputMask:CIImage?
var inputRefractiveIndex: Float = 4.0
var inputLensScale: Float = 50
public var inputLightingAmount: Float = 1.5
var inputLensBlur: CGFloat = 0
public var inputBackgroundBlur: CGFloat = 2
var inputRadius: Float = 15
override public func setDefaults()
{
inputRefractiveIndex = 4.0
inputLensScale = 50
inputLightingAmount = 1.5
inputRadius = 15
inputLensBlur = 0
inputBackgroundBlur = 2
}
override public var outputImage: CIImage! {
guard let inputImage = inputImage, let refractingKernel = refractingKernel else {
return nil
}
let extent = inputImage.extent
let arguments = [inputImage,
inputMask!,
inputRefractiveIndex,
inputLensScale,
inputLightingAmount] as [Any]
return refractingKernel.apply(extent: extent,
roiCallback: {
(index, rect) in
return rect
},
arguments: arguments)!
}
let refractingKernel = CIKernel(source:
"float lumaAtOffset(sampler source, vec2 origin, vec2 offset)" +
"{" +
" vec3 pixel = sample(source, samplerTransform(source, origin + offset)).rgb;" +
" float luma = dot(pixel, vec3(0.2126, 0.7152, 0.0722));" +
" return luma;" +
"}" +
"kernel vec4 lumaBasedRefract(sampler image, sampler refractingImage, float refractiveIndex, float lensScale, float lightingAmount) \n" +
"{ " +
" vec2 d = destCoord();" +
" float northLuma = lumaAtOffset(refractingImage, d, vec2(0.0, -1.0));" +
" float southLuma = lumaAtOffset(refractingImage, d, vec2(0.0, 1.0));" +
" float westLuma = lumaAtOffset(refractingImage, d, vec2(-1.0, 0.0));" +
" float eastLuma = lumaAtOffset(refractingImage, d, vec2(1.0, 0.0));" +
" vec3 lensNormal = normalize(vec3((eastLuma - westLuma), (southLuma - northLuma), 1.0));" +
" vec3 refractVector = refract(vec3(0.0, 0.0, 1.0), lensNormal, refractiveIndex) * lensScale; " +
" vec3 outputPixel = sample(image, samplerTransform(image, d + refractVector.xy)).rgb;" +
" outputPixel += (northLuma - southLuma) * lightingAmount ;" +
" outputPixel += (eastLuma - westLuma) * lightingAmount ;" +
" return vec4(outputPixel, 1.0);" +
"}"
)
}
使用法
let filterMask = Mask()
let filter = Refraction()
var imgOriginal:CIImage!
var imgMask:CIImage!
var imgEdited:CIImage!
// I have a set of sliders that update a tuple and send an action that executes the following code
filterMask.inputRadius = sliders.valuePCP.3
imgMask = filterMask.outputImage
filter.inputMask = imgMask
filter.inputRefractiveIndex = sliders.valuePCP.0
filter.inputLensScale = sliders.valuePCP.1
filter.inputLightingAmount = sliders.valuePCP.2
imgEdited = filter.outputImage
希望します。
あなたはいくつかのコードが不足しているように見えます(私に)。なぜ、 'inputImage'は' CIVector'で、何らかのイメージではありません(おそらく 'CIImage')?それが問題ではない場合、おそらく 'CustomFilter'を作るためのコードをもっと提供することができますか? – dfd
ありがとうございました!名前が間違っていたのは間違いありません。しかし私は、その意味をより明確にするために質問を再編集しました。 –
まだちょっと混乱しているかもしれませんが、私は* CIFilter'や 'CIKernel'を3通り使っています - そのうちの1つだけが' CIFilter'をサブクラス化する必要があります。私は自分のコード(Swift 3と4の両方)と - 例えば 'public var inputImage:CIImage? 'をチェックしました。私のクラス 'public'(それはフレームワークターゲットの一部です)を宣言する以外に、私はなぜあなたが問題を抱えているのか見ていません。ビルドエラーが発生していますか?ランタイムエラー? – dfd