Skip to content

Instantly share code, notes, and snippets.

@tail-call
Created March 14, 2024 04:10
Show Gist options
  • Save tail-call/a31e67f087497e7c1c9c3f73bcad2728 to your computer and use it in GitHub Desktop.
Save tail-call/a31e67f087497e7c1c9c3f73bcad2728 to your computer and use it in GitHub Desktop.
UIImage noise animation generator
import UIKit
public extension UIImage {
static var noiseAnimation: UIImage = {
makeNoiseAnimation(
size: CGSize(width: 226, height: 168),
framesCount: 4,
magnitude: 0.5,
duration: 0.2
) ?? UIImage()
}()
}
// MARK: - Implementation
private func makeNoiseAnimation(
size: CGSize,
framesCount: Int,
magnitude: Double,
duration: TimeInterval
) -> UIImage? {
UIImage.animatedImage(
with: (0..<framesCount).compactMap { _ in
makeNoiseImage(size: size, magnitude: magnitude)
},
duration: duration
)
}
private func makeNoiseImage(size: CGSize, magnitude: Double) -> UIImage? {
let width = Int(size.width)
let height = Int(size.height)
let bytesPerPixel = 4
let bytesPerRow = width * bytesPerPixel
let imageData = UnsafeMutablePointer<UInt8>.allocate(
capacity: width * height * bytesPerPixel
)
for y in 0..<height {
for x in 0..<width {
let offset = y * bytesPerRow + x * bytesPerPixel
let intensity = UInt8(Double(arc4random() % 256) * magnitude)
imageData[offset] = UInt8(intensity) // Red
imageData[offset + 1] = UInt8(intensity) // Green
imageData[offset + 2] = UInt8(intensity) // Blue
imageData[offset + 3] = 255 // Alpha
}
}
let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue
guard let context = CGContext(data: imageData, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: bitmapInfo) else {
return nil
}
guard let cgImage = context.makeImage() else {
return nil
}
return UIImage(cgImage: cgImage)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment