mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
117 lines
4.3 KiB
Swift
117 lines
4.3 KiB
Swift
import UIKit
|
|
import Accelerate
|
|
|
|
private func imageBuffer(from data: UnsafeMutableRawPointer!, width: vImagePixelCount, height: vImagePixelCount, rowBytes: Int) -> vImage_Buffer {
|
|
return vImage_Buffer(data: data, height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: rowBytes)
|
|
}
|
|
|
|
public func blurredImage(_ image: UIImage, radius: CGFloat, iterations: Int = 3) -> UIImage? {
|
|
guard let cgImage = image.cgImage, let providerData = cgImage.dataProvider?.data else {
|
|
return nil
|
|
}
|
|
|
|
if image.size.width <= 0.0 || image.size.height <= 0 || radius <= 0 {
|
|
return image
|
|
}
|
|
|
|
var boxSize = UInt32(radius)
|
|
if boxSize % 2 == 0 {
|
|
boxSize += 1
|
|
}
|
|
|
|
let bytes = cgImage.bytesPerRow * cgImage.height
|
|
let inData = malloc(bytes)
|
|
var inBuffer = imageBuffer(from: inData, width: vImagePixelCount(cgImage.width), height: vImagePixelCount(cgImage.height), rowBytes: cgImage.bytesPerRow)
|
|
|
|
let outData = malloc(bytes)
|
|
var outBuffer = imageBuffer(from: outData, width: vImagePixelCount(cgImage.width), height: vImagePixelCount(cgImage.height), rowBytes: cgImage.bytesPerRow)
|
|
|
|
let tempSize = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, 0, 0, boxSize, boxSize, nil, vImage_Flags(kvImageEdgeExtend + kvImageGetTempBufferSize))
|
|
let tempData = malloc(tempSize)
|
|
|
|
defer {
|
|
free(inData)
|
|
free(outData)
|
|
free(tempData)
|
|
}
|
|
|
|
|
|
let source = CFDataGetBytePtr(providerData)
|
|
memcpy(inBuffer.data, source, bytes)
|
|
|
|
|
|
for _ in 0 ..< iterations {
|
|
vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, tempData, 0, 0, boxSize, boxSize, nil, vImage_Flags(kvImageEdgeExtend))
|
|
|
|
let temp = inBuffer.data
|
|
inBuffer.data = outBuffer.data
|
|
outBuffer.data = temp
|
|
}
|
|
|
|
let context = cgImage.colorSpace.flatMap {
|
|
CGContext(data: inBuffer.data, width: cgImage.width, height: cgImage.height, bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: cgImage.bytesPerRow, space: $0, bitmapInfo: cgImage.bitmapInfo.rawValue)
|
|
}
|
|
|
|
let blurredCGImage = context?.makeImage()
|
|
if let blurredCGImage = blurredCGImage {
|
|
return UIImage(cgImage: blurredCGImage, scale: image.scale, orientation: image.imageOrientation)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public func verticalBlurredImage(_ image: UIImage, radius: CGFloat, iterations: Int = 3) -> UIImage? {
|
|
guard let cgImage = image.cgImage, let providerData = cgImage.dataProvider?.data else {
|
|
return nil
|
|
}
|
|
|
|
if image.size.width <= 0.0 || image.size.height <= 0 || radius <= 0 {
|
|
return image
|
|
}
|
|
|
|
var boxSize = UInt32(radius)
|
|
if boxSize % 2 == 0 {
|
|
boxSize += 1
|
|
}
|
|
|
|
let bytes = cgImage.bytesPerRow * cgImage.height
|
|
let inData = malloc(bytes)
|
|
var inBuffer = imageBuffer(from: inData, width: vImagePixelCount(cgImage.width), height: vImagePixelCount(cgImage.height), rowBytes: cgImage.bytesPerRow)
|
|
|
|
let outData = malloc(bytes)
|
|
var outBuffer = imageBuffer(from: outData, width: vImagePixelCount(cgImage.width), height: vImagePixelCount(cgImage.height), rowBytes: cgImage.bytesPerRow)
|
|
|
|
let tempSize = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, 0, 0, boxSize, 1, nil, vImage_Flags(kvImageEdgeExtend + kvImageGetTempBufferSize))
|
|
let tempData = malloc(tempSize)
|
|
|
|
defer {
|
|
free(inData)
|
|
free(outData)
|
|
free(tempData)
|
|
}
|
|
|
|
|
|
let source = CFDataGetBytePtr(providerData)
|
|
memcpy(inBuffer.data, source, bytes)
|
|
|
|
|
|
for _ in 0 ..< iterations {
|
|
vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, tempData, 0, 0, boxSize, 1, nil, vImage_Flags(kvImageEdgeExtend))
|
|
|
|
let temp = inBuffer.data
|
|
inBuffer.data = outBuffer.data
|
|
outBuffer.data = temp
|
|
}
|
|
|
|
let context = cgImage.colorSpace.flatMap {
|
|
CGContext(data: inBuffer.data, width: cgImage.width, height: cgImage.height, bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: cgImage.bytesPerRow, space: $0, bitmapInfo: cgImage.bitmapInfo.rawValue)
|
|
}
|
|
|
|
let blurredCGImage = context?.makeImage()
|
|
if let blurredCGImage = blurredCGImage {
|
|
return UIImage(cgImage: blurredCGImage, scale: image.scale, orientation: image.imageOrientation)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|