Simplify images, tag overview
This commit is contained in:
@ -15,20 +15,33 @@ final class ImageGenerator {
|
||||
self.storage = storage
|
||||
self.settings = settings
|
||||
self.generatedImages = storage.loadListOfGeneratedImages() ?? [:]
|
||||
print("ImageGenerator: Loaded list of \(totalImageCount) already generated images")
|
||||
}
|
||||
|
||||
private var outputFolder: String {
|
||||
settings.paths.imagesOutputFolderPath
|
||||
}
|
||||
|
||||
private var totalImageCount: Int {
|
||||
generatedImages.values.reduce(0) { $0 + $1.count }
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func save() -> Bool {
|
||||
guard storage.save(listOfGeneratedImages: generatedImages) else {
|
||||
print("Failed to save list of generated images")
|
||||
print("ImageGenerator: Failed to save list of generated images")
|
||||
return false
|
||||
}
|
||||
print("ImageGenerator: Saved list of \(totalImageCount) images")
|
||||
return true
|
||||
}
|
||||
|
||||
private var avifCommands: Set<String> = []
|
||||
|
||||
func printAvifCommands() {
|
||||
avifCommands.sorted().forEach { print($0) }
|
||||
}
|
||||
|
||||
/**
|
||||
Remove all versions of an image, so that they will be recreated on the next run.
|
||||
|
||||
@ -44,26 +57,27 @@ final class ImageGenerator {
|
||||
print("Image generator: \(generatedImages.count)/\(images.count) images (\(versionCount) versions)")
|
||||
}
|
||||
|
||||
private func needsToGenerate(version: String, for image: String) -> Bool {
|
||||
if exists(version) {
|
||||
private func hasPreviouslyGenerated(_ version: ImageVersion) -> Bool {
|
||||
guard let versions = generatedImages[version.image.id] else {
|
||||
return false
|
||||
}
|
||||
guard let versions = generatedImages[image] else {
|
||||
return true
|
||||
}
|
||||
guard versions.contains(version) else {
|
||||
return true
|
||||
}
|
||||
return !exists(version)
|
||||
return versions.contains(version.versionId)
|
||||
}
|
||||
|
||||
private func hasNowGenerated(version: String, for image: String) {
|
||||
guard var versions = generatedImages[image] else {
|
||||
generatedImages[image] = [version]
|
||||
return
|
||||
private func needsToGenerate(_ version: ImageVersion) -> Bool {
|
||||
if hasPreviouslyGenerated(version) {
|
||||
return false
|
||||
}
|
||||
versions.insert(version)
|
||||
generatedImages[image] = versions
|
||||
if exists(version) {
|
||||
// Mark as already generated
|
||||
hasNowGenerated(version)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private func hasNowGenerated(_ version: ImageVersion) {
|
||||
generatedImages[version.image.id, default: []].insert(version.versionId)
|
||||
}
|
||||
|
||||
private func removeVersions(for image: String) {
|
||||
@ -72,53 +86,59 @@ final class ImageGenerator {
|
||||
|
||||
// MARK: Files
|
||||
|
||||
private func exists(_ image: String) -> Bool {
|
||||
storage.hasFileInOutputFolder(relativePath(for: image))
|
||||
private func exists(_ version: ImageVersion) -> Bool {
|
||||
storage.hasFileInOutputFolder(version.outputPath)
|
||||
}
|
||||
|
||||
private func relativePath(for image: String) -> String {
|
||||
outputFolder + "/" + image
|
||||
}
|
||||
|
||||
private func write(imageData data: Data, version: String) -> Bool {
|
||||
return storage.write(data, to: relativePath(for: version))
|
||||
private func write(imageData data: Data, of version: ImageVersion) -> Bool {
|
||||
return storage.write(data, to: version.outputPath)
|
||||
}
|
||||
|
||||
// MARK: Image operations
|
||||
|
||||
func generate(job: ImageGenerationJob) -> Bool {
|
||||
guard needsToGenerate(version: job.version, for: job.image) else {
|
||||
func generate(version: ImageVersion) -> Bool {
|
||||
guard needsToGenerate(version) else {
|
||||
return true
|
||||
}
|
||||
|
||||
guard let data = storage.fileData(for: job.image) else {
|
||||
print("Failed to load image \(job.image)")
|
||||
guard let data = version.image.dataContent() else {
|
||||
print("ImageGenerator: Failed to load data for image \(version.image.id)")
|
||||
return false
|
||||
}
|
||||
|
||||
guard let originalImage = NSImage(data: data) else {
|
||||
print("Failed to load image")
|
||||
print("ImageGenerator: Failed to load image \(version.image.id)")
|
||||
return false
|
||||
}
|
||||
|
||||
let representation = create(image: originalImage, width: CGFloat(job.maximumWidth), height: CGFloat(job.maximumHeight))
|
||||
let representation = create(image: originalImage, width: CGFloat(version.maximumWidth), height: CGFloat(version.maximumHeight))
|
||||
|
||||
guard let data = create(image: representation, type: job.type, quality: job.quality) else {
|
||||
print("Failed to get data for type \(job.type)")
|
||||
guard let data = create(image: representation, type: version.type, quality: version.quality) else {
|
||||
print("ImageGenerator: Failed to get data for type \(version.type) of image \(version.image.id)")
|
||||
return false
|
||||
}
|
||||
|
||||
if job.type == .avif {
|
||||
let input = job.version.fileNameAndExtension.fileName + "." + job.image.fileExtension!
|
||||
print("avifenc -q 70 \(input) \(job.version)")
|
||||
hasNowGenerated(version: job.version, for: job.image)
|
||||
if version.type == .avif {
|
||||
// AVIF conversion is very slow, so we save bash commands
|
||||
// for the conversion instead
|
||||
let baseVersion = ImageVersion(
|
||||
image: version.image,
|
||||
type: version.image.type,
|
||||
maximumWidth: version.maximumWidth,
|
||||
maximumHeight: version.maximumHeight)
|
||||
let originalImagePath = storage.outputPath(to: baseVersion.outputPath)!.path()
|
||||
let generatedImagePath = storage.outputPath(to: version.outputPath)!.path()
|
||||
let quality = Int(version.quality * 100)
|
||||
|
||||
avifCommands.insert("avifenc -q \(quality) '\(originalImagePath)' '\(generatedImagePath)'")
|
||||
// hasNowGenerated(version)
|
||||
return true
|
||||
}
|
||||
|
||||
guard write(imageData: data, version: job.version) else {
|
||||
guard write(imageData: data, of: version) else {
|
||||
return false
|
||||
}
|
||||
hasNowGenerated(version: job.version, for: job.image)
|
||||
hasNowGenerated(version)
|
||||
return true
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user