another.im-ios/ConversationsClassic/AppCore/Files/FileProcessing.swift
2024-07-13 03:29:46 +02:00

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
}
}