[ad_1]
I’ve round 50 3D LUTs (saved as png photos, every being 900KB in dimension) and use CIColorCube filter to generate a filtered picture. I take advantage of UICollectionView to show filtered thumbnails (100×100) for every LUT (like in Images app). The issue is UICollectionView scrolling turns into extraordinarily sluggish(no the place near smoothness of Images app) once I generate filtered photos as person scrolls. I considered pre producing filtered photos however the issue is it takes round 150 milliseconds to generate cubeData from LUT png, so for 50 thumbnails it takes round 7-8 seconds to arrange filtered thumbnails which is lengthy. And that is precisely the offender for scrolling efficiency as effectively. I’m questioning what I can do to make it clean like in Images app or different picture modifying apps. Right here is my code to generate dice information from LUT png. I consider there’s extra of a CoreImage/Metallic trick to repair the problem than UIKit/DispatchQueue/NSOperation based mostly fixes.
public static func colorCubeDataFromLUTPNGImage(_ picture : UIImage, lutSize:Int) -> Information? {
let dimension = lutSize
let lutImage = picture.cgImage!
let lutWidth = lutImage.width
let lutHeight = lutImage.top
let rowCount = lutHeight / dimension
let columnCount = lutWidth / dimension
if ((lutWidth % dimension != 0) || (lutHeight % dimension != 0) || (rowCount * columnCount != dimension)) {
NSLog("Invalid colorLUT")
return nil
}
let bitmap = getBytesFromImage(picture: picture)!
let floatSize = MemoryLayout<Float>.dimension
let cubeData = UnsafeMutablePointer<Float>.allocate(capability: dimension * dimension * dimension * 4 * floatSize)
var z = 0
var bitmapOffset = 0
for _ in 0 ..< rowCount {
for y in 0 ..< dimension {
let tmp = z
for _ in 0 ..< columnCount {
for x in 0 ..< dimension {
let alpha = Float(bitmap[bitmapOffset]) / 255.0
let purple = Float(bitmap[bitmapOffset+1]) / 255.0
let inexperienced = Float(bitmap[bitmapOffset+2]) / 255.0
let blue = Float(bitmap[bitmapOffset+3]) / 255.0
let dataOffset = (z * dimension * dimension + y * dimension + x) * 4
cubeData[dataOffset + 3] = alpha
cubeData[dataOffset + 2] = purple
cubeData[dataOffset + 1] = inexperienced
cubeData[dataOffset + 0] = blue
bitmapOffset += 4
}
z += 1
}
z = tmp
}
z += columnCount
}
let colorCubeData = Information(bytesNoCopy: cubeData, rely: dimension * dimension * dimension * 4 * floatSize, deallocator: Information.Deallocator.free)
return colorCubeData
}
fileprivate static func getBytesFromImage(picture:UIImage?) -> [UInt8]?
{
var pixelValues: [UInt8]?
if let imageRef = picture?.cgImage CGBitmapInfo.byteOrder32Little.rawValue
let colorSpace = CGColorSpaceCreateDeviceRGB()
var intensities = [UInt8](repeating: 0, rely: totalBytes)
let contextRef = CGContext(information: &intensities, width: width, top: top, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, house: colorSpace, bitmapInfo: bitmapInfo)
contextRef?.draw(imageRef, in: CGRect(x: 0.0, y: 0.0, width: CGFloat(width), top: CGFloat(top)))
pixelValues = intensities
return pixelValues!
}
And right here is my code for UICollectionViewCell setup:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let lutPath = self.lutPaths[indexPath.item]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FilterCell", for: indexPath) as! FilterCell
if let lutImage = UIImage(contentsOfFile: lutPath) {
let renderer = CIFilter(identify: "CIColorCube")!
let lutData = ColorCubeHelper.colorCubeDataFromLUTPNGImage(lutImage, lutSize: 64)
renderer.setValue(lutData!, forKey: "inputCubeData")
renderer.setValue(64, forKey: "inputCubeDimension")
renderer.setValue(inputCIImage, forKey: kCIInputImageKey)
let outputImage = renderer.outputImage!
let cgImage = self.ciContext.createCGImage(outputImage, from: outputImage.extent)!
cell.configure(picture: UIImage(cgImage: cgImage))
} else {
NSLog("LUT not discovered at (indexPath.merchandise)")
}
return cell
}
[ad_2]
