DEVTOOLS-186 Exporter les images de resgen en svg
Some checks failed
gitea-openium/resgen.swift/pipeline/head There was a failure building this commit
gitea-openium/resgen.swift/pipeline/pr-master There was a failure building this commit

This commit is contained in:
Quentin Bandera 2024-04-22 12:05:24 +02:00
parent d4afa9c9e9
commit 2357a40fff
6 changed files with 194 additions and 47 deletions

View File

@ -8,9 +8,12 @@
import Foundation import Foundation
import ToolCore import ToolCore
class XcassetsGenerator { enum OutputImageExtension: String {
case png
case svg
}
static let outputImageExtension = "png" class XcassetsGenerator {
let forceGeneration: Bool let forceGeneration: Bool
@ -60,9 +63,9 @@ class XcassetsGenerator {
generatedAssetsPaths.append(imagesetName) generatedAssetsPaths.append(imagesetName)
// Generate output images path // Generate output images path
let output1x = "\(imagesetPath)/\(parsedImage.name).\(XcassetsGenerator.outputImageExtension)" let output1x = "\(imagesetPath)/\(parsedImage.name).\(OutputImageExtension.png.rawValue)"
let output2x = "\(imagesetPath)/\(parsedImage.name)@2x.\(XcassetsGenerator.outputImageExtension)" let output2x = "\(imagesetPath)/\(parsedImage.name)@2x.\(OutputImageExtension.png.rawValue)"
let output3x = "\(imagesetPath)/\(parsedImage.name)@3x.\(XcassetsGenerator.outputImageExtension)" let output3x = "\(imagesetPath)/\(parsedImage.name)@3x.\(OutputImageExtension.png.rawValue)"
// Check if we need to convert image // Check if we need to convert image
guard self.shouldGenerate(inputImagePath: imageData.path, xcassetImagePath: output1x) else { guard self.shouldGenerate(inputImagePath: imageData.path, xcassetImagePath: output1x) else {
@ -82,9 +85,22 @@ class XcassetsGenerator {
} }
} }
// Convert image
let convertArguments = parsedImage.convertArguments let convertArguments = parsedImage.convertArguments
if imageData.ext == "svg" {
if parsedImage.imageExtensions.contains(.vector) {
let output = "\(imagesetPath)/\(parsedImage.name).\(OutputImageExtension.svg.rawValue)"
let tempURL = URL(fileURLWithPath: output)
do {
if FileManager.default.fileExists(atPath: tempURL.path) {
try FileManager.default.removeItem(atPath: tempURL.path)
}
try FileManager.default.copyItem(atPath: imageData.path, toPath: tempURL.path)
} catch {
print(error.localizedDescription)
}
} else 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 -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 -w 200 -o path/to/output.png
// /usr/local/bin/rsvg-convert path/to/image.png -h 300 -o path/to/output.png // /usr/local/bin/rsvg-convert path/to/image.png -h 300 -o path/to/output.png

View File

@ -7,14 +7,30 @@
import Foundation import Foundation
enum TemplateRenderingIntent: String, Codable {
case template
case original
}
struct AssetContent: Codable, Equatable { struct AssetContent: Codable, Equatable {
let images: [AssetImageDescription] let images: [AssetImageDescription]
let info: AssetInfo let info: AssetInfo
let properties: AssetProperties?
init(
images: [AssetImageDescription],
info: AssetInfo,
properties: AssetProperties? = nil
) {
self.images = images
self.info = info
self.properties = properties
}
static func == (lhs: AssetContent, rhs: AssetContent) -> Bool { static func == (lhs: AssetContent, rhs: AssetContent) -> Bool {
guard lhs.images.count == rhs.images.count else { return false } guard lhs.images.count == rhs.images.count else { return false }
let lhsImages = lhs.images.sorted(by: { $0.scale < $1.scale }) let lhsImages = lhs.images.sorted(by: { $0.filename < $1.filename })
let rhsImages = rhs.images.sorted(by: { $0.scale < $1.scale }) let rhsImages = rhs.images.sorted(by: { $0.filename < $1.filename })
return lhsImages == rhsImages return lhsImages == rhsImages
} }
@ -22,11 +38,39 @@ struct AssetContent: Codable, Equatable {
struct AssetImageDescription: Codable, Equatable { struct AssetImageDescription: Codable, Equatable {
let idiom: String let idiom: String
let scale: String let scale: String?
let filename: String let filename: String
init(
idiom: String,
scale: String? = nil,
filename: String
) {
self.idiom = idiom
self.scale = scale
self.filename = filename
}
} }
struct AssetInfo: Codable, Equatable { struct AssetInfo: Codable, Equatable {
let version: Int let version: Int
let author: String let author: String
} }
struct AssetProperties: Codable, Equatable {
let preservesVectorRepresentation: Bool
let templateRenderingIntent: TemplateRenderingIntent?
init(
preservesVectorRepresentation: Bool,
templateRenderingIntent: TemplateRenderingIntent? = nil
) {
self.preservesVectorRepresentation = preservesVectorRepresentation
self.templateRenderingIntent = templateRenderingIntent
}
enum CodingKeys: String, CodingKey {
case preservesVectorRepresentation = "preserves-vector-representation"
case templateRenderingIntent = "template-rendering-intent"
}
}

View File

@ -7,11 +7,30 @@
import Foundation import Foundation
enum ImageExtension: String {
case vector
}
struct ParsedImage { struct ParsedImage {
let name: String let name: String
let tags: String let tags: String
let width: Int let width: Int
let height: Int let height: Int
let imageExtensions: [ImageExtension]
init(
name: String,
tags: String,
width: Int,
height: Int,
imageExtensions: [ImageExtension] = []
) {
self.name = name
self.tags = tags
self.width = width
self.height = height
self.imageExtensions = imageExtensions
}
// MARK: - Convert // MARK: - Convert
@ -56,22 +75,41 @@ struct ParsedImage {
} }
var imageContent: AssetContent { var imageContent: AssetContent {
if imageExtensions.contains(.vector) {
return AssetContent(
images: [
AssetImageDescription(
idiom: "universal",
filename: "\(name).\(OutputImageExtension.svg.rawValue)"
)
],
info: AssetInfo(
version: 1,
author: "ResgenSwift-Imagium"
),
properties: AssetProperties(
preservesVectorRepresentation: true,
templateRenderingIntent: .template
)
)
} else {
return AssetContent( return AssetContent(
images: [ images: [
AssetImageDescription( AssetImageDescription(
idiom: "universal", idiom: "universal",
scale: "1x", scale: "1x",
filename: "\(name).\(XcassetsGenerator.outputImageExtension)" filename: "\(name).\(OutputImageExtension.png.rawValue)"
), ),
AssetImageDescription( AssetImageDescription(
idiom: "universal", idiom: "universal",
scale: "2x", scale: "2x",
filename: "\(name)@2x.\(XcassetsGenerator.outputImageExtension)" filename: "\(name)@2x.\(OutputImageExtension.png.rawValue)"
), ),
AssetImageDescription( AssetImageDescription(
idiom: "universal", idiom: "universal",
scale: "3x", scale: "3x",
filename: "\(name)@3x.\(XcassetsGenerator.outputImageExtension)" filename: "\(name)@3x.\(OutputImageExtension.png.rawValue)"
) )
], ],
info: AssetInfo( info: AssetInfo(
@ -80,6 +118,7 @@ struct ParsedImage {
) )
) )
} }
}
// MARK: - Extension property // MARK: - Extension property

View File

@ -39,10 +39,20 @@ class ImageFileParser {
return Int(splittedLine[3])! return Int(splittedLine[3])!
}() }()
let image = ParsedImage(name: String(splittedLine[1]), tags: String(splittedLine[0]), width: width, height: height) var imageExtensions: [ImageExtension] = []
splittedLine.forEach { stringExtension in
if let imageExtension = ImageExtension(rawValue: String(stringExtension)) {
imageExtensions.append(imageExtension)
}
}
let image = ParsedImage(name: String(splittedLine[1]), tags: String(splittedLine[0]), width: width, height: height, imageExtensions: imageExtensions)
imagesToGenerate.append(image) imagesToGenerate.append(image)
} }
print(imagesToGenerate)
return imagesToGenerate.filter { return imagesToGenerate.filter {
$0.tags.contains(platform.rawValue) $0.tags.contains(platform.rawValue)
} }

View File

@ -17,8 +17,8 @@ class ImageFileParserTests: XCTestCase {
# #
# SMAAS Support # SMAAS Support
# #
id image_one 25 ? id image_one 25 ? vector
di image_two ? 50 di image_two ? 50 webp vector
d image_three 25 ? d image_three 25 ?
d image_four 75 ? d image_four 75 ?
""" """
@ -38,6 +38,7 @@ class ImageFileParserTests: XCTestCase {
XCTAssertEqual(firstImage!.tags, "id") XCTAssertEqual(firstImage!.tags, "id")
XCTAssertEqual(firstImage!.width, 25) XCTAssertEqual(firstImage!.width, 25)
XCTAssertEqual(firstImage!.height, -1) XCTAssertEqual(firstImage!.height, -1)
XCTAssertEqual(firstImage!.imageExtensions, [.vector])
let secondImage = parsedImages.first { let secondImage = parsedImages.first {
$0.name == "image_two" $0.name == "image_two"
@ -46,5 +47,6 @@ class ImageFileParserTests: XCTestCase {
XCTAssertEqual(secondImage!.tags, "di") XCTAssertEqual(secondImage!.tags, "di")
XCTAssertEqual(secondImage!.width, -1) XCTAssertEqual(secondImage!.width, -1)
XCTAssertEqual(secondImage!.height, 50) XCTAssertEqual(secondImage!.height, 50)
XCTAssertEqual(firstImage!.imageExtensions, [.vector])
} }
} }

View File

@ -135,17 +135,17 @@ final class ParsedImageTests: XCTestCase {
AssetImageDescription( AssetImageDescription(
idiom: "universal", idiom: "universal",
scale: "1x", scale: "1x",
filename: "\(parsedImage.name).\(XcassetsGenerator.outputImageExtension)" filename: "\(parsedImage.name).\(OutputImageExtension.png.rawValue)"
), ),
AssetImageDescription( AssetImageDescription(
idiom: "universal", idiom: "universal",
scale: "2x", scale: "2x",
filename: "\(parsedImage.name)@2x.\(XcassetsGenerator.outputImageExtension)" filename: "\(parsedImage.name)@2x.\(OutputImageExtension.png.rawValue)"
), ),
AssetImageDescription( AssetImageDescription(
idiom: "universal", idiom: "universal",
scale: "3x", scale: "3x",
filename: "\(parsedImage.name)@3x.\(XcassetsGenerator.outputImageExtension)" filename: "\(parsedImage.name)@3x.\(OutputImageExtension.png.rawValue)"
) )
], ],
info: AssetInfo( info: AssetInfo(
@ -156,4 +156,40 @@ final class ParsedImageTests: XCTestCase {
XCTAssertEqual(property, expect) XCTAssertEqual(property, expect)
} }
func testAssetVector() {
// Given
let imageName = "the_name"
let parsedImage = ParsedImage(name: imageName,
tags: "id",
width: 10,
height: 10,
imageExtensions: [.vector])
// When
let property = parsedImage.imageContent
// Expect
let expect = AssetContent(
images: [
AssetImageDescription(
idiom: "universal",
filename: "\(parsedImage.name).\(OutputImageExtension.svg.rawValue)"
)
],
info: AssetInfo(
version: 1,
author: "ResgenSwift-Imagium"
),
properties: AssetProperties(
preservesVectorRepresentation: true,
templateRenderingIntent: .template
)
)
debugPrint(property)
debugPrint(expect)
XCTAssertEqual(property, expect)
}
} }