Skip to content

Commit

Permalink
Edits and variations images (#45)
Browse files Browse the repository at this point in the history
* Add new edit image endpoint

* Create new folder structure

* Add image variations

* Refactor

* Update README
  • Loading branch information
SwiftBeta committed May 17, 2024
1 parent 0e5d8ba commit b316788
Show file tree
Hide file tree
Showing 40 changed files with 1,004 additions and 63 deletions.
90 changes: 86 additions & 4 deletions Demo/Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
F442DD342B8119A20032682E /* VisionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F442DD332B8119A20032682E /* VisionViewModel.swift */; };
F44D5A1D2BF55D5D007B2D3F /* CreateTranslationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44D5A1C2BF55D5D007B2D3F /* CreateTranslationView.swift */; };
F44D5A1F2BF55D7D007B2D3F /* CreateTranslationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44D5A1E2BF55D7D007B2D3F /* CreateTranslationViewModel.swift */; };
F4AA12212BF72F6100F2B6BB /* EditImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA12202BF72F6100F2B6BB /* EditImageView.swift */; };
F4AA12232BF72F8900F2B6BB /* EditImageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA12222BF72F8900F2B6BB /* EditImageViewModel.swift */; };
F4EAB7B62BF7B8D700ECA18F /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EAB7B52BF7B8D700ECA18F /* Line.swift */; };
F4EAB7B82BF7B8E000ECA18F /* Point.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EAB7B72BF7B8E000ECA18F /* Point.swift */; };
F4EAB7BA2BF7B8EE00ECA18F /* SwiftBetaCanvas.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EAB7B92BF7B8EE00ECA18F /* SwiftBetaCanvas.swift */; };
F4EAB7BC2BF7B8FE00ECA18F /* View+ReverseMask.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EAB7BB2BF7B8FE00ECA18F /* View+ReverseMask.swift */; };
F4EAB7C12BF7B93E00ECA18F /* GalleryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EAB7C02BF7B93E00ECA18F /* GalleryView.swift */; };
F4EAB7C32BF7B94C00ECA18F /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EAB7C22BF7B94C00ECA18F /* CameraView.swift */; };
F4EAB7C62BF7F47C00ECA18F /* VariationImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EAB7C52BF7F47C00ECA18F /* VariationImageView.swift */; };
F4EAB7C82BF7F48800ECA18F /* VariationImageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EAB7C72BF7F48800ECA18F /* VariationImageViewModel.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -56,6 +66,16 @@
F442DD332B8119A20032682E /* VisionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisionViewModel.swift; sourceTree = "<group>"; };
F44D5A1C2BF55D5D007B2D3F /* CreateTranslationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateTranslationView.swift; sourceTree = "<group>"; };
F44D5A1E2BF55D7D007B2D3F /* CreateTranslationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateTranslationViewModel.swift; sourceTree = "<group>"; };
F4AA12202BF72F6100F2B6BB /* EditImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditImageView.swift; sourceTree = "<group>"; };
F4AA12222BF72F8900F2B6BB /* EditImageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditImageViewModel.swift; sourceTree = "<group>"; };
F4EAB7B52BF7B8D700ECA18F /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
F4EAB7B72BF7B8E000ECA18F /* Point.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Point.swift; sourceTree = "<group>"; };
F4EAB7B92BF7B8EE00ECA18F /* SwiftBetaCanvas.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftBetaCanvas.swift; sourceTree = "<group>"; };
F4EAB7BB2BF7B8FE00ECA18F /* View+ReverseMask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+ReverseMask.swift"; sourceTree = "<group>"; };
F4EAB7C02BF7B93E00ECA18F /* GalleryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryView.swift; sourceTree = "<group>"; };
F4EAB7C22BF7B94C00ECA18F /* CameraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
F4EAB7C52BF7F47C00ECA18F /* VariationImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VariationImageView.swift; sourceTree = "<group>"; };
F4EAB7C72BF7F48800ECA18F /* VariationImageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VariationImageViewModel.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -92,10 +112,8 @@
F442DCF62B80A2B20032682E /* DemoApp.swift */,
F442DCF82B80A2B20032682E /* ContentView.swift */,
F442DD092B80A3D10032682E /* ChatCompletions */,
F442DD1C2B80B74E0032682E /* CreateImages */,
F442DD262B8110C10032682E /* CreateAudio */,
F442DD2B2B8113B40032682E /* CreateTranscription */,
F44D5A1B2BF55D50007B2D3F /* CreateTranslation */,
F4AA121F2BF72EB300F2B6BB /* Image */,
F4AA121E2BF72EAB00F2B6BB /* Audio */,
F442DD302B8119770032682E /* Vision */,
F442DCFA2B80A2B30032682E /* Assets.xcassets */,
F442DD1A2B80A5990032682E /* SwiftOpenAI.plist */,
Expand Down Expand Up @@ -195,6 +213,58 @@
path = CreateTranslation;
sourceTree = "<group>";
};
F4AA121D2BF72E9600F2B6BB /* EditImage */ = {
isa = PBXGroup;
children = (
F4AA12202BF72F6100F2B6BB /* EditImageView.swift */,
F4AA12222BF72F8900F2B6BB /* EditImageViewModel.swift */,
F4EAB7B42BF7B8CC00ECA18F /* Dependencies */,
);
path = EditImage;
sourceTree = "<group>";
};
F4AA121E2BF72EAB00F2B6BB /* Audio */ = {
isa = PBXGroup;
children = (
F442DD262B8110C10032682E /* CreateAudio */,
F442DD2B2B8113B40032682E /* CreateTranscription */,
F44D5A1B2BF55D50007B2D3F /* CreateTranslation */,
);
path = Audio;
sourceTree = "<group>";
};
F4AA121F2BF72EB300F2B6BB /* Image */ = {
isa = PBXGroup;
children = (
F4EAB7C42BF7F47000ECA18F /* VariationImage */,
F442DD1C2B80B74E0032682E /* CreateImages */,
F4AA121D2BF72E9600F2B6BB /* EditImage */,
);
path = Image;
sourceTree = "<group>";
};
F4EAB7B42BF7B8CC00ECA18F /* Dependencies */ = {
isa = PBXGroup;
children = (
F4EAB7B52BF7B8D700ECA18F /* Line.swift */,
F4EAB7B72BF7B8E000ECA18F /* Point.swift */,
F4EAB7B92BF7B8EE00ECA18F /* SwiftBetaCanvas.swift */,
F4EAB7BB2BF7B8FE00ECA18F /* View+ReverseMask.swift */,
F4EAB7C02BF7B93E00ECA18F /* GalleryView.swift */,
F4EAB7C22BF7B94C00ECA18F /* CameraView.swift */,
);
path = Dependencies;
sourceTree = "<group>";
};
F4EAB7C42BF7F47000ECA18F /* VariationImage */ = {
isa = PBXGroup;
children = (
F4EAB7C52BF7F47C00ECA18F /* VariationImageView.swift */,
F4EAB7C72BF7F48800ECA18F /* VariationImageViewModel.swift */,
);
path = VariationImage;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -272,25 +342,35 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4AA12232BF72F8900F2B6BB /* EditImageViewModel.swift in Sources */,
F442DD2D2B8114330032682E /* CreateTranscriptView.swift in Sources */,
F4EAB7C62BF7F47C00ECA18F /* VariationImageView.swift in Sources */,
F442DD202B80B7810032682E /* CreateImagesView.swift in Sources */,
F44D5A1F2BF55D7D007B2D3F /* CreateTranslationViewModel.swift in Sources */,
F442DD0B2B80A3E80032682E /* ChatView.swift in Sources */,
F442DD0F2B80A4330032682E /* TextMessageView.swift in Sources */,
F44D5A1D2BF55D5D007B2D3F /* CreateTranslationView.swift in Sources */,
F4AA12212BF72F6100F2B6BB /* EditImageView.swift in Sources */,
F442DD232B80B79C0032682E /* LoadingView.swift in Sources */,
F4EAB7B62BF7B8D700ECA18F /* Line.swift in Sources */,
F442DD162B80A4E40032682E /* ChatCompletionsViewModel.swift in Sources */,
F4EAB7BC2BF7B8FE00ECA18F /* View+ReverseMask.swift in Sources */,
F442DD2F2B8114450032682E /* CreateTranscriptViewModel.swift in Sources */,
F442DCF92B80A2B20032682E /* ContentView.swift in Sources */,
F4EAB7C82BF7F48800ECA18F /* VariationImageViewModel.swift in Sources */,
F442DD192B80A57D0032682E /* Bundle+OpenAIAPIKey.swift in Sources */,
F442DD282B8110FA0032682E /* CreateAudioView.swift in Sources */,
F442DD132B80A4760032682E /* TypingIndicatorView.swift in Sources */,
F4EAB7C12BF7B93E00ECA18F /* GalleryView.swift in Sources */,
F442DD252B80B7C70032682E /* CreateImageViewModel.swift in Sources */,
F442DCF72B80A2B20032682E /* DemoApp.swift in Sources */,
F442DD2A2B8111190032682E /* CreateAudioViewModel.swift in Sources */,
F4EAB7C32BF7B94C00ECA18F /* CameraView.swift in Sources */,
F442DD322B8119900032682E /* VisionView.swift in Sources */,
F442DD342B8119A20032682E /* VisionViewModel.swift in Sources */,
F4EAB7BA2BF7B8EE00ECA18F /* SwiftBetaCanvas.swift in Sources */,
F442DD0D2B80A4230032682E /* ConversationView.swift in Sources */,
F4EAB7B82BF7B8E000ECA18F /* Point.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -427,6 +507,7 @@
DEVELOPMENT_TEAM = K4FV5B8ZC4;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSCameraUsageDescription = "We need access to your camera so you can take photos.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
Expand Down Expand Up @@ -456,6 +537,7 @@
DEVELOPMENT_TEAM = K4FV5B8ZC4;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSCameraUsageDescription = "We need access to your camera so you can take photos.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
Expand Down
File renamed without changes.
42 changes: 42 additions & 0 deletions Demo/Demo/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import SwiftOpenAI
struct ContentView: View {
@State var chatCompletionsViewModel: ChatCompletionsViewModel = .init()
@State var createImagesViewModel: CreateImageViewModel = .init()
@State var editImageViewModel: EditImageViewModel = .init()
@State var variationImageViewModel: VariationImageViewModel = .init()
@State var createAudioViewModel: CreateAudioViewModel = .init()
@State var createTranscriptViewModel: CreateTranscriptViewModel = .init()
@State var createTranslationViewModel: CreateTranslationViewModel = .init()
Expand Down Expand Up @@ -52,6 +54,46 @@ struct ContentView: View {
}
}
}
NavigationLink {
EditImageView(viewModel: editImageViewModel)
.navigationBarTitleDisplayMode(.large)
.navigationTitle("Edit Image")
} label: {
HStack {
Image(systemName: "photo.badge.checkmark.fill")
.foregroundStyle(.white)
.frame(width: 40, height: 40)
.padding(4)
.background(.pink.gradient)
.clipShape(RoundedRectangle(cornerRadius: 10))
VStack(alignment: .leading) {
Text("Edit Image")
.font(.system(size: 18))
.bold()
Text("Learn how to edit images with masks and prompts")
}
}
}
NavigationLink {
VariationImageView(viewModel: variationImageViewModel)
.navigationBarTitleDisplayMode(.large)
.navigationTitle("Variate Image")
} label: {
HStack {
Image(systemName: "die.face.6.fill")
.foregroundStyle(.white)
.frame(width: 40, height: 40)
.padding(4)
.background(.cyan.gradient)
.clipShape(RoundedRectangle(cornerRadius: 10))
VStack(alignment: .leading) {
Text("Variation Image")
.font(.system(size: 18))
.bold()
Text("Learn how to get a variation of images")
}
}
}
NavigationLink {
CreateAudioView(viewModel: createAudioViewModel)
.navigationBarTitleDisplayMode(.large)
Expand Down
53 changes: 53 additions & 0 deletions Demo/Demo/Image/EditImage/Dependencies/CameraView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// CameraView.swift
// OpenAI
//
// Created by Home on 4/11/22.
//

import Foundation
import UIKit
import SwiftUI

public struct CameraView: UIViewControllerRepresentable {
@Binding var selectedImage: Image?
@Environment(\.dismiss) var dismiss

public init(selectedImage: Binding<Image?>) {
self._selectedImage = selectedImage
}

public func makeUIViewController(context: Context) -> some UIViewController {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = context.coordinator
imagePickerController.sourceType = .camera
imagePickerController.allowsEditing = true
imagePickerController.showsCameraControls = true
return imagePickerController
}

public func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
// Empty
}

public func makeCoordinator() -> Coordinator {
Coordinator(cameraView: self)
}
}

final public class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var cameraView: CameraView

init(cameraView: CameraView) {
self.cameraView = cameraView
}

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
cameraView.selectedImage = Image(uiImage: image)
}
cameraView.dismiss()
}
}
45 changes: 45 additions & 0 deletions Demo/Demo/Image/EditImage/Dependencies/GalleryView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Foundation
import UIKit
import SwiftUI

public struct GalleryView: UIViewControllerRepresentable {
@Binding var selectedImage: Image?
@Environment(\.dismiss) var dismiss

public init(selectedImage: Binding<Image?>) {
self._selectedImage = selectedImage
}

public func makeUIViewController(context: Context) -> some UIViewController {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = context.coordinator
imagePickerController.sourceType = .photoLibrary
imagePickerController.allowsEditing = true
return imagePickerController
}

public func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
// Empty
}

public func makeCoordinator() -> GalleryCoordinator {
GalleryCoordinator(galleryView: self)
}
}

final public class GalleryCoordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var galleryView: GalleryView

init(galleryView: GalleryView) {
self.galleryView = galleryView
}

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
galleryView.selectedImage = Image(uiImage: image)
}
galleryView.dismiss()
}
}
14 changes: 14 additions & 0 deletions Demo/Demo/Image/EditImage/Dependencies/Line.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation
import SwiftUI

public struct Line {
var points: [Point]
var color: Color
var width: Float

public init(points: [Point], color: Color, width: Float) {
self.points = points
self.color = color
self.width = width
}
}
11 changes: 11 additions & 0 deletions Demo/Demo/Image/EditImage/Dependencies/Point.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

public struct Point {
let currentPoint: CGPoint
let lastPoint: CGPoint

public init(currentPoint: CGPoint, lastPoint: CGPoint) {
self.currentPoint = currentPoint
self.lastPoint = lastPoint
}
}
Loading

0 comments on commit b316788

Please sign in to comment.