I'm building an app for iPhone using Swift 4. I have a few test filters. Both work fine through the camera's output, but when I'm creating an array of images out of the more complex one, my memory overflows to catastrophic proportions and crashes my app.
I'm calling this one below in a loop which overflows my memory:
func rotateHue2(with ciImage: CIImage,
rotatedByHue deltaHueRadians: CGFloat,
orientation:UIImageOrientation?,
screenWidth:CGFloat,
screenHeight:CGFloat) -> UIImage {
let sourceCore = ciImage
let transBG = UIImage(color: .clear, size: CGSize(width: screenWidth, height: screenHeight))
let transBGCI = CIImage(cgImage: (transBG?.cgImage)!)
// Part 1
let gradientPoint0Pos: [CGFloat] = [0, 0]
let inputPoint0Vector = CIVector(values: gradientPoint0Pos, count: gradientPoint0Pos.count)
var gradientPoint1Pos: [CGFloat]
if(orientation == nil){
gradientPoint1Pos = [0, screenWidth*2]
}else{
gradientPoint1Pos = [screenHeight*2, 0]
}
let inputPoint1Vector = CIVector(values: gradientPoint1Pos, count: gradientPoint1Pos.count)
let gradientFilter = CIFilter(name: "CISmoothLinearGradient")
gradientFilter?.setDefaults()
gradientFilter?.setValue(inputPoint0Vector, forKey: "inputPoint0")
gradientFilter?.setValue(inputPoint1Vector, forKey: "inputPoint1")
gradientFilter?.setValue(CIColor.clear, forKey:"inputColor0")
gradientFilter?.setValue(CIColor.black, forKey:"inputColor1")
let gradient = gradientFilter?.outputImage?
.cropped(to: sourceCore.extent)
let hue1 = sourceCore
.applyingFilter("CIHueAdjust", parameters: [kCIInputImageKey: sourceCore,
kCIInputAngleKey: deltaHueRadians])
.cropped(to: sourceCore.extent)
let alphaMaskBlend1 = CIFilter(name: "CIBlendWithAlphaMask",
withInputParameters: [kCIInputImageKey: hue1,
kCIInputBackgroundImageKey: transBGCI,
kCIInputMaskImageKey:gradient!])?.outputImage?
.cropped(to: sourceCore.extent)
// Part 2
let hue2 = sourceCore
.applyingFilter("CIHueAdjust", parameters: [kCIInputImageKey: sourceCore,
kCIInputAngleKey: deltaHueRadians+1.5707])
.cropped(to: sourceCore.extent)
let blendedMasks = hue2
.applyingFilter(compositeOperationFilters[compositeOperationFiltersIndex], parameters: [kCIInputImageKey: alphaMaskBlend1!,
kCIInputBackgroundImageKey: hue2])
.cropped(to: sourceCore.extent)
// Convert the filter output back into a UIImage.
let context = CIContext(options: nil)
let resultRef = context.createCGImage(blendedMasks, from: blendedMasks.extent)
var result:UIImage? = nil
if(orientation != nil){
result = UIImage(cgImage: resultRef!, scale: 1.0, orientation: orientation!)
}else{
result = UIImage(cgImage: resultRef!)
}
return result!
}
Each image is resized down to 1280 or 720 wide depending on the phone's orientation. Why does this give me a memory warning when my other image filter works fine?
Just for kicks, here's the other one that doesn't make it crash:
func rotateHue(with ciImage: CIImage,
rotatedByHue deltaHueRadians: CGFloat,
orientation:UIImageOrientation?,
screenWidth:CGFloat,
screenHeight:CGFloat) -> UIImage {
// Create a Core Image version of the image.
let sourceCore = ciImage
// Apply a CIHueAdjust filter
let hueAdjust = CIFilter(name: "CIHueAdjust")
hueAdjust?.setDefaults()
hueAdjust?.setValue(sourceCore, forKey: "inputImage")
hueAdjust?.setValue(deltaHueRadians, forKey: "inputAngle")
let resultCore = CIFilter(name: "CIHueAdjust",
withInputParameters: [kCIInputImageKey: sourceCore,
kCIInputAngleKey: deltaHueRadians])?.outputImage?
.cropped(to: sourceCore.extent)
// Convert the filter output back into a UIImage.
let context = CIContext(options: nil)
let resultRef = context.createCGImage(resultCore!, from: (resultCore?.extent)!)
var result:UIImage? = nil
if(orientation != nil){
result = UIImage(cgImage: resultRef!, scale: 1.0, orientation: orientation!)
}else{
result = UIImage(cgImage: resultRef!)
}
return result!
}