diff --git a/README.md b/README.md index 64d624f..570d42a 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ You can see how it works through the simple sample code. ![Image](images/ss0_1280.png) ## Change Log +- [1.1.0 (5)] - Dec 21, 2022 `[Added]` + - Added the negative prompt. It requires the latest apple/ml-stable-diffusion Swift Package. - [1.0.3 (4)] - Dec 18, 2022 `[Changed]` - set `MLModelConfiguration.computeUnits` to `.cpuAndGPU`, when running on mobile devices. - [1.0.2 (3)] - Dec 16, 2022 `[Changed]` diff --git a/imggensd2.xcodeproj/project.pbxproj b/imggensd2.xcodeproj/project.pbxproj index bdcce6c..0d4cead 100644 --- a/imggensd2.xcodeproj/project.pbxproj +++ b/imggensd2.xcodeproj/project.pbxproj @@ -7,13 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - BA01CAE9294C92FC00C89D87 /* StableDiffusion in Frameworks */ = {isa = PBXBuildFile; productRef = BA01CAE8294C92FC00C89D87 /* StableDiffusion */; }; BA03C378293D785C001426DE /* imggensd2App.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA03C377293D785C001426DE /* imggensd2App.swift */; }; BA03C37A293D785C001426DE /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA03C379293D785C001426DE /* ContentView.swift */; }; BA03C37C293D785D001426DE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BA03C37B293D785D001426DE /* Assets.xcassets */; }; BA03C37F293D785D001426DE /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BA03C37E293D785D001426DE /* Preview Assets.xcassets */; }; BA03C388293D80A4001426DE /* CoreMLModels in Resources */ = {isa = PBXBuildFile; fileRef = BA03C387293D80A4001426DE /* CoreMLModels */; }; BA03C38D293D8773001426DE /* ImageGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA03C38C293D8773001426DE /* ImageGenerator.swift */; }; + BA1E84232952ED66001701EA /* StableDiffusion in Frameworks */ = {isa = PBXBuildFile; productRef = BA1E84222952ED66001701EA /* StableDiffusion */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -32,7 +32,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BA01CAE9294C92FC00C89D87 /* StableDiffusion in Frameworks */, + BA1E84232952ED66001701EA /* StableDiffusion in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -95,7 +95,7 @@ ); name = imggensd2; packageProductDependencies = ( - BA01CAE8294C92FC00C89D87 /* StableDiffusion */, + BA1E84222952ED66001701EA /* StableDiffusion */, ); productName = imggensd2; productReference = BA03C374293D785C001426DE /* imggensd2.app */; @@ -126,7 +126,7 @@ ); mainGroup = BA03C36B293D785C001426DE; packageReferences = ( - BA01CAE7294C92FB00C89D87 /* XCRemoteSwiftPackageReference "ml-stable-diffusion" */, + BA1E84212952ED66001701EA /* XCRemoteSwiftPackageReference "ml-stable-diffusion" */, ); productRefGroup = BA03C375293D785C001426DE /* Products */; projectDirPath = ""; @@ -305,7 +305,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_ASSET_PATHS = "\"imggensd2/Preview Content\""; DEVELOPMENT_TEAM = J5CY9Q9UP5; ENABLE_PREVIEWS = YES; @@ -321,7 +321,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.3; + MARKETING_VERSION = 1.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.atarayosd.imggensd2; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -336,7 +336,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_ASSET_PATHS = "\"imggensd2/Preview Content\""; DEVELOPMENT_TEAM = J5CY9Q9UP5; ENABLE_PREVIEWS = YES; @@ -352,7 +352,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.3; + MARKETING_VERSION = 1.1.0; PRODUCT_BUNDLE_IDENTIFIER = com.atarayosd.imggensd2; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -385,9 +385,9 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - BA01CAE7294C92FB00C89D87 /* XCRemoteSwiftPackageReference "ml-stable-diffusion" */ = { + BA1E84212952ED66001701EA /* XCRemoteSwiftPackageReference "ml-stable-diffusion" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/apple/ml-stable-diffusion#swift-requirements"; + repositoryURL = "https://github.com/apple/ml-stable-diffusion"; requirement = { branch = main; kind = branch; @@ -396,9 +396,9 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - BA01CAE8294C92FC00C89D87 /* StableDiffusion */ = { + BA1E84222952ED66001701EA /* StableDiffusion */ = { isa = XCSwiftPackageProductDependency; - package = BA01CAE7294C92FB00C89D87 /* XCRemoteSwiftPackageReference "ml-stable-diffusion" */; + package = BA1E84212952ED66001701EA /* XCRemoteSwiftPackageReference "ml-stable-diffusion" */; productName = StableDiffusion; }; /* End XCSwiftPackageProductDependency section */ diff --git a/imggensd2.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/imggensd2.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index fc21992..7dabea9 100644 --- a/imggensd2.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/imggensd2.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,12 +1,12 @@ { "pins" : [ { - "identity" : "ml-stable-diffusion#swift-requirements", + "identity" : "ml-stable-diffusion", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/ml-stable-diffusion#swift-requirements", + "location" : "https://github.com/apple/ml-stable-diffusion", "state" : { "branch" : "main", - "revision" : "66dde8da135593eccef7bbb3a329ccf7bb1724d3" + "revision" : "c90b705334c3807f4f4042cbb351b59cbe5c6f7b" } }, { diff --git a/imggensd2/ContentView.swift b/imggensd2/ContentView.swift index da3626d..dc7b086 100644 --- a/imggensd2/ContentView.swift +++ b/imggensd2/ContentView.swift @@ -8,9 +8,17 @@ import SwiftUI struct ContentView: View { + static let prompt = "a photo of an astronaut riding a horse on mars" + static let negativePrompt = +""" +lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, + cropped, worst quality, low quality, normal quality, jpeg artifacts, blurry, multiple legs, malformation +""" + @StateObject var imageGenerator = ImageGenerator() @State private var generationParameter = - ImageGenerator.GenerationParameter(prompt: "a photo of an astronaut riding a horse on mars", + ImageGenerator.GenerationParameter(prompt: prompt, + negativePrompt: negativePrompt, seed: 100, stepCount: 20, imageCount: 1, disableSafety: false) var body: some View { @@ -46,19 +54,23 @@ struct ContentView: View { } } -// struct ContentView_Previews: PreviewProvider { -// static var previews: some View { -// ContentView() -// } -// } +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} struct PromptView: View { @Binding var parameter: ImageGenerator.GenerationParameter var body: some View { VStack { + HStack { Text("Prompt:"); Spacer() } TextField("Prompt:", text: $parameter.prompt) .textFieldStyle(RoundedBorderTextFieldStyle()) + HStack { Text("Negative Prompt:"); Spacer() } + TextField("Negative Prompt:", text: $parameter.negativePrompt) + .textFieldStyle(RoundedBorderTextFieldStyle()) Stepper(value: $parameter.imageCount, in: 1...10) { Text("Image Count: \(parameter.imageCount)") } diff --git a/imggensd2/ImageGenerator.swift b/imggensd2/ImageGenerator.swift index 965a60d..7cdfcf4 100644 --- a/imggensd2/ImageGenerator.swift +++ b/imggensd2/ImageGenerator.swift @@ -13,6 +13,7 @@ import CoreML final class ImageGenerator: ObservableObject { struct GenerationParameter { var prompt: String + var negativePrompt: String var seed: Int var stepCount: Int var imageCount: Int @@ -26,6 +27,7 @@ final class ImageGenerator: ObservableObject { struct GeneratedImages { let prompt: String + let negativePrompt: String let imageCount: Int let stepCount: Int let seed: Int @@ -50,6 +52,8 @@ final class ImageGenerator: ObservableObject { @Published var generationState: GenerationState = .idle @Published var generatedImages: GeneratedImages? + @Published var isPipelineCreated = false + private var sdPipeline: StableDiffusionPipeline? init() { @@ -61,6 +65,7 @@ final class ImageGenerator: ObservableObject { func setPipeline(_ pipeline: StableDiffusionPipeline) { // for actor isolation sdPipeline = pipeline + isPipelineCreated = true } func setGeneratedImages(_ images: GeneratedImages) { // for actor isolation @@ -102,9 +107,10 @@ final class ImageGenerator: ObservableObject { // https://github.com/ynagatomo/ARDiffMuseum // It handles the progressHandler and displays the generating images step by step. let cgImages = try sdPipeline.generateImages(prompt: parameter.prompt, + negativePrompt: parameter.negativePrompt, imageCount: parameter.imageCount, stepCount: parameter.stepCount, - seed: parameter.seed, + seed: UInt32(parameter.seed), disableSafety: parameter.disableSafety) print("images were generated.") let uiImages = cgImages.compactMap { image in @@ -112,6 +118,7 @@ final class ImageGenerator: ObservableObject { } else { return nil } } await self.setGeneratedImages(GeneratedImages(prompt: parameter.prompt, + negativePrompt: parameter.negativePrompt, imageCount: parameter.imageCount, stepCount: parameter.stepCount, seed: parameter.seed,