CIImage内存未释放
CIImage memory not released
我正在尝试拍摄一系列图像,同时混合 X 图像并生成新图像。这是我必须完成的代码:
static func blendImages(blendFrames: Int, blendMode: CIImage.BlendMode, imagePaths: [URL], completion: @escaping (_ progress: Double) -> Void) {
var currentIndex = 0
while currentIndex + blendFrames < imagePaths.count {
let currentSubset = Array(imagePaths[currentIndex..<(currentIndex + blendFrames)])
var currentSubsetIndex = 0
var firstImage: CIImage?
while currentSubset.count > currentSubsetIndex + 1 {
if firstImage == nil { firstImage = CIImage(contentsOf: currentSubset[currentSubsetIndex]) } //First image allocated in memory
if let secondImage = CIImage(contentsOf: currentSubset[currentSubsetIndex + 1]) {//Second image allocated in memory
firstImage = firstImage?.blend(with: secondImage, blendMode: blendMode)
} //Would expect secondImage to be freed from memory at this point, but it does not happen
currentSubsetIndex += 1
}
if let finalImage = firstImage {
let bitMapRep = NSBitmapImageRep(ciImage: finalImage)
let data = bitMapRep.representation(using: .jpeg, properties: [:])
do {
try data?.write(to: URL(fileURLWithPath: "Final-" + String(format: "%03d", currentIndex) + ".jpg"))
} catch let error as NSError {
print("Failed to write to disk: \(error)")
}
}
firstImage = nil //Would expect firstImage to be freed from memory at this point (or at beginning of next cycle in while-loop), but it does not happen
currentIndex += 1
}
}
以及 CIImage 的 blend
函数的代码
extension CIImage {
enum BlendMode: String {
case Lighten = "CILightenBlendMode"
case Darken = "CIDarkenBlendMode"
}
func blend(with image: CIImage, blendMode: BlendMode) -> CIImage? {
let filter = CIFilter(name: blendMode.rawValue)!
filter.setDefaults()
filter.setValue(self, forKey: "inputImage")
filter.setValue(image, forKey: "inputBackgroundImage")
return filter.outputImage
}
}
如代码注释中所述,我希望在 firstImage 和 secondImage 中分配的内存在创建它们的范围结束时被释放。因为它们都是在 while 循环中创建的,所以我会期望它们在该循环结束时被释放,但是,这似乎没有发生。但是这里没有内存泄漏,因为当 blendImages
函数完成时,内存被适当地释放(但是,这为时已晚,因为代码可以 运行 处理数百或数千张图像,使应用程序在释放之前消耗数 TB 的数据)。
如果有人能看到我的代码中的缺陷以及如何提高内存效率,我们将不胜感激。
您应该使用autoreleasepool
函数来强制释放其范围内的对象。此功能将帮助您更精确地管理内存占用。
static func blendImages(blendFrames: Int, blendMode: CIImage.BlendMode, imagePaths: [URL], completion: @escaping (_ progress: Double) -> Void) {
var currentIndex = 0
while currentIndex + blendFrames < imagePaths.count {
autorelease {
// your code
}
currentIndex += 1
}
}
您可以查看此 post 以获得更多信息。
我正在尝试拍摄一系列图像,同时混合 X 图像并生成新图像。这是我必须完成的代码:
static func blendImages(blendFrames: Int, blendMode: CIImage.BlendMode, imagePaths: [URL], completion: @escaping (_ progress: Double) -> Void) {
var currentIndex = 0
while currentIndex + blendFrames < imagePaths.count {
let currentSubset = Array(imagePaths[currentIndex..<(currentIndex + blendFrames)])
var currentSubsetIndex = 0
var firstImage: CIImage?
while currentSubset.count > currentSubsetIndex + 1 {
if firstImage == nil { firstImage = CIImage(contentsOf: currentSubset[currentSubsetIndex]) } //First image allocated in memory
if let secondImage = CIImage(contentsOf: currentSubset[currentSubsetIndex + 1]) {//Second image allocated in memory
firstImage = firstImage?.blend(with: secondImage, blendMode: blendMode)
} //Would expect secondImage to be freed from memory at this point, but it does not happen
currentSubsetIndex += 1
}
if let finalImage = firstImage {
let bitMapRep = NSBitmapImageRep(ciImage: finalImage)
let data = bitMapRep.representation(using: .jpeg, properties: [:])
do {
try data?.write(to: URL(fileURLWithPath: "Final-" + String(format: "%03d", currentIndex) + ".jpg"))
} catch let error as NSError {
print("Failed to write to disk: \(error)")
}
}
firstImage = nil //Would expect firstImage to be freed from memory at this point (or at beginning of next cycle in while-loop), but it does not happen
currentIndex += 1
}
}
以及 CIImage 的 blend
函数的代码
extension CIImage {
enum BlendMode: String {
case Lighten = "CILightenBlendMode"
case Darken = "CIDarkenBlendMode"
}
func blend(with image: CIImage, blendMode: BlendMode) -> CIImage? {
let filter = CIFilter(name: blendMode.rawValue)!
filter.setDefaults()
filter.setValue(self, forKey: "inputImage")
filter.setValue(image, forKey: "inputBackgroundImage")
return filter.outputImage
}
}
如代码注释中所述,我希望在 firstImage 和 secondImage 中分配的内存在创建它们的范围结束时被释放。因为它们都是在 while 循环中创建的,所以我会期望它们在该循环结束时被释放,但是,这似乎没有发生。但是这里没有内存泄漏,因为当 blendImages
函数完成时,内存被适当地释放(但是,这为时已晚,因为代码可以 运行 处理数百或数千张图像,使应用程序在释放之前消耗数 TB 的数据)。
如果有人能看到我的代码中的缺陷以及如何提高内存效率,我们将不胜感激。
您应该使用autoreleasepool
函数来强制释放其范围内的对象。此功能将帮助您更精确地管理内存占用。
static func blendImages(blendFrames: Int, blendMode: CIImage.BlendMode, imagePaths: [URL], completion: @escaping (_ progress: Double) -> Void) {
var currentIndex = 0
while currentIndex + blendFrames < imagePaths.count {
autorelease {
// your code
}
currentIndex += 1
}
}
您可以查看此 post 以获得更多信息。