73 lines
2.7 KiB
Swift
73 lines
2.7 KiB
Swift
import Foundation
|
|
import UIKit
|
|
|
|
final class FileProcessing {
|
|
static let shared = FileProcessing()
|
|
|
|
static var fileFolder: URL {
|
|
// swiftlint:disable:next force_unwrapping
|
|
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
return documentsURL.appendingPathComponent(Const.fileFolder)
|
|
}
|
|
|
|
func createThumbnail(id: String, localUrl: URL) -> URL? {
|
|
// make path for thumbnail
|
|
let thumbnailUrl = FileProcessing.fileFolder.appendingPathComponent(id).appendingPathExtension("png")
|
|
|
|
// check if thumbnail already exists
|
|
if FileManager.default.fileExists(atPath: thumbnailUrl.path) {
|
|
return thumbnailUrl
|
|
}
|
|
|
|
// create thumbnail if not exists
|
|
switch localUrl.lastPathComponent.attachmentType {
|
|
case .image:
|
|
guard let image = UIImage(contentsOfFile: localUrl.path) else { return nil }
|
|
let targetSize = CGSize(width: Const.attachmentPreviewSize, height: Const.attachmentPreviewSize)
|
|
guard let thumbnail = scaleAndCropImage(image, targetSize) else { return nil }
|
|
guard let data = thumbnail.pngData() else { return nil }
|
|
do {
|
|
try data.write(to: thumbnailUrl)
|
|
return thumbnailUrl
|
|
} catch {
|
|
return nil
|
|
}
|
|
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension FileProcessing {
|
|
func scaleAndCropImage(_ img: UIImage, _ size: CGSize) -> UIImage? {
|
|
guard let cgImage = img.cgImage else {
|
|
return nil
|
|
}
|
|
let contextImage: UIImage = .init(cgImage: cgImage)
|
|
var contextSize: CGSize = contextImage.size
|
|
|
|
var posX: CGFloat = 0.0
|
|
var posY: CGFloat = 0.0
|
|
let cgwidth: CGFloat = size.width
|
|
let cgheight: CGFloat = size.height
|
|
|
|
// Check and handle if the image is wider than the requested size
|
|
if contextSize.width > contextSize.height {
|
|
posX = ((contextSize.width - contextSize.height) / 2)
|
|
contextSize.width = contextSize.height
|
|
} else if contextSize.width < contextSize.height {
|
|
// Check and handle if the image is taller than the requested size
|
|
posY = ((contextSize.height - contextSize.width) / 2)
|
|
contextSize.height = contextSize.width
|
|
}
|
|
|
|
let rect: CGRect = .init(x: posX, y: posY, width: cgwidth, height: cgheight)
|
|
guard let contextCg = contextImage.cgImage, let imgRef = contextCg.cropping(to: rect) else {
|
|
return nil
|
|
}
|
|
let image: UIImage = .init(cgImage: imgRef, scale: img.scale, orientation: img.imageOrientation)
|
|
return image
|
|
}
|
|
}
|