Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit
172 lines
7.2 KiB
Swift
172 lines
7.2 KiB
Swift
//
|
|
// XcassetsGenerator.swift
|
|
//
|
|
//
|
|
// Created by Thibaut Schmitt on 24/01/2022.
|
|
//
|
|
|
|
import Foundation
|
|
import ToolCore
|
|
|
|
class XcassetsGenerator {
|
|
|
|
static let outputImageExtension = "png"
|
|
|
|
let forceGeneration: Bool
|
|
|
|
// MARK: - Init
|
|
|
|
init(forceGeneration: Bool) {
|
|
self.forceGeneration = forceGeneration
|
|
}
|
|
|
|
// MARK: - Assets generation
|
|
|
|
func generateXcassets(inputPath: String, imagesToGenerate: [ParsedImage], xcassetsPath: String) {
|
|
let fileManager = FileManager()
|
|
let svgConverter = Images.getSvgConverterPath()
|
|
let allSubFiles = fileManager.getAllRegularFileIn(directory: inputPath)
|
|
|
|
var generatedAssetsPaths = [String]()
|
|
|
|
// Generate new assets
|
|
imagesToGenerate.forEach { parsedImage in
|
|
// Get image path
|
|
let imageData: (path: String, ext: String) = {
|
|
for subfile in allSubFiles {
|
|
if subfile.hasSuffix("/" + parsedImage.name + ".svg") {
|
|
return (subfile, "svg")
|
|
}
|
|
if subfile.hasSuffix("/" + parsedImage.name + ".png") {
|
|
return (subfile, "png")
|
|
}
|
|
if subfile.hasSuffix("/" + parsedImage.name + ".jpg") {
|
|
return (subfile, "jpg")
|
|
}
|
|
if subfile.hasSuffix("/" + parsedImage.name + ".jepg") {
|
|
return (subfile, "jepg")
|
|
}
|
|
}
|
|
let error = ImagesError.unknownImageExtension(parsedImage.name)
|
|
print(error.description)
|
|
Images.exit(withError: error)
|
|
}()
|
|
|
|
// Create imageset folder name
|
|
let imagesetName = "\(parsedImage.name).imageset"
|
|
let imagesetPath = "\(xcassetsPath)/\(imagesetName)"
|
|
|
|
// Store managed images path
|
|
generatedAssetsPaths.append(imagesetName)
|
|
|
|
// Generate output images path
|
|
let output1x = "\(imagesetPath)/\(parsedImage.name).\(XcassetsGenerator.outputImageExtension)"
|
|
let output2x = "\(imagesetPath)/\(parsedImage.name)@2x.\(XcassetsGenerator.outputImageExtension)"
|
|
let output3x = "\(imagesetPath)/\(parsedImage.name)@3x.\(XcassetsGenerator.outputImageExtension)"
|
|
|
|
// Check if we need to convert image
|
|
guard self.shouldGenerate(inputImagePath: imageData.path, xcassetImagePath: output1x) else {
|
|
//print("\(parsedImage.name) -> Not regenerating")
|
|
return
|
|
}
|
|
|
|
// Create imageset folder
|
|
if fileManager.fileExists(atPath: imagesetPath) == false {
|
|
do {
|
|
try fileManager.createDirectory(atPath: imagesetPath,
|
|
withIntermediateDirectories: true)
|
|
} catch {
|
|
let error = ImagesError.createAssetFolder(imagesetPath)
|
|
print(error.description)
|
|
Images.exit(withError: error)
|
|
}
|
|
}
|
|
|
|
// Convert image
|
|
let convertArguments = parsedImage.convertArguments
|
|
if imageData.ext == "svg" {
|
|
// /usr/local/bin/rsvg-convert path/to/image.png -w 200 -h 300 -o path/to/output.png
|
|
// /usr/local/bin/rsvg-convert path/to/image.png -w 200 -o path/to/output.png
|
|
// /usr/local/bin/rsvg-convert path/to/image.png -h 300 -o path/to/output.png
|
|
var command1x = ["\(svgConverter)", "\(imageData.path)"]
|
|
var command2x = ["\(svgConverter)", "\(imageData.path)"]
|
|
var command3x = ["\(svgConverter)", "\(imageData.path)"]
|
|
|
|
self.addConvertArgument(command: &command1x, convertArgument: convertArguments.x1)
|
|
self.addConvertArgument(command: &command2x, convertArgument: convertArguments.x2)
|
|
self.addConvertArgument(command: &command3x, convertArgument: convertArguments.x3)
|
|
|
|
command1x.append(contentsOf: ["-o", output1x])
|
|
command2x.append(contentsOf: ["-o", output2x])
|
|
command3x.append(contentsOf: ["-o", output3x])
|
|
|
|
Shell.shell(command1x)
|
|
Shell.shell(command2x)
|
|
Shell.shell(command3x)
|
|
} else {
|
|
// convert path/to/image.png -resize 200x300 path/to/output.png
|
|
// convert path/to/image.png -resize 200x path/to/output.png
|
|
// convert path/to/image.png -resize x300 path/to/output.png
|
|
Shell.shell(["convert", "\(imageData.path)",
|
|
"-resize", "\(convertArguments.x1.width ?? "")x\(convertArguments.x1.height ?? "")",
|
|
output1x])
|
|
Shell.shell(["convert", "\(imageData.path)",
|
|
"-resize", "\(convertArguments.x2.width ?? "")x\(convertArguments.x2.height ?? "")",
|
|
output2x])
|
|
Shell.shell(["convert", "\(imageData.path)",
|
|
"-resize", "\(convertArguments.x3.width ?? "")x\(convertArguments.x3.height ?? "")",
|
|
output3x])
|
|
}
|
|
|
|
// Write Content.json
|
|
let imagesetContentJson = parsedImage.contentJson
|
|
let contentJsonFilePath = "\(imagesetPath)/Contents.json"
|
|
|
|
let contentJsonFilePathURL = URL(fileURLWithPath: contentJsonFilePath)
|
|
try! imagesetContentJson.write(to: contentJsonFilePathURL, atomically: false, encoding: .utf8)
|
|
|
|
print("\(parsedImage.name) -> Generated")
|
|
}
|
|
|
|
// Success info
|
|
let generatedAssetsCount = generatedAssetsPaths.count
|
|
print("Images generated: \(generatedAssetsCount)")
|
|
|
|
// Delete old assets
|
|
let allImagesetName = Set(fileManager.getAllImageSetFolderIn(directory: xcassetsPath))
|
|
let imagesetToRemove = allImagesetName.subtracting(Set(generatedAssetsPaths))
|
|
|
|
imagesetToRemove.forEach {
|
|
print("Will remove: \($0)")
|
|
}
|
|
|
|
imagesetToRemove.forEach { itemToRemove in
|
|
try! fileManager.removeItem(atPath: "\(xcassetsPath)/\(itemToRemove)")
|
|
}
|
|
print("Removed \(imagesetToRemove.count) images")
|
|
}
|
|
|
|
// MARK: - Helpers: SVG command
|
|
|
|
private func addConvertArgument(command: inout [String], convertArgument: ConvertArgument) {
|
|
if let width = convertArgument.width, width.isEmpty == false {
|
|
command.append("-w")
|
|
command.append("\(width)")
|
|
}
|
|
if let height = convertArgument.height, height.isEmpty == false {
|
|
command.append("-h")
|
|
command.append("\(height)")
|
|
}
|
|
}
|
|
|
|
// MARK: - Helpers: bypass generation
|
|
|
|
private func shouldGenerate(inputImagePath: String, xcassetImagePath: String) -> Bool {
|
|
if forceGeneration {
|
|
return true
|
|
}
|
|
|
|
return GeneratorChecker.isFile(inputImagePath, moreRecenThan: xcassetImagePath)
|
|
}
|
|
}
|