|
@@ -57,6 +57,14 @@ class DrawViewController: UIViewController {
|
|
|
return imageView
|
|
|
}()
|
|
|
|
|
|
+ lazy var remindText: UILabel = {
|
|
|
+ var label = UILabel()
|
|
|
+ label.text = "长按图片进行保存"
|
|
|
+ label.textColor = .systemGray5
|
|
|
+ label.textAlignment = .center
|
|
|
+ return label
|
|
|
+ }()
|
|
|
+
|
|
|
var prompt = ""
|
|
|
var tranPrompt = ""
|
|
|
var negativePrompt = ""
|
|
@@ -70,17 +78,20 @@ class DrawViewController: UIViewController {
|
|
|
override func viewDidLoad() {
|
|
|
super.viewDidLoad()
|
|
|
|
|
|
- view.backgroundColor = .white
|
|
|
+ if UITraitCollection.current.userInterfaceStyle == .dark {
|
|
|
+ view.backgroundColor = .black
|
|
|
+ } else {
|
|
|
+ view.backgroundColor = .white
|
|
|
+ }
|
|
|
+
|
|
|
self.title = "AI Paint"
|
|
|
-
|
|
|
delegate = UIApplication.shared.delegate as? AppDelegate
|
|
|
- context = delegate!.persistentContainer.viewContext
|
|
|
- painting = NSEntityDescription.insertNewObject(forEntityName: "Painting", into: context!) as? Painting
|
|
|
|
|
|
view.addSubview(generateView)
|
|
|
generateView.addSubview(promptTextField)
|
|
|
generateView.addSubview(negativePromptTextField)
|
|
|
generateView.addSubview(generateButton)
|
|
|
+ view.addSubview(remindText)
|
|
|
|
|
|
view.addSubview(generateImage)
|
|
|
longPress = UILongPressGestureRecognizer(target: self, action: #selector(saveImageToPhotos))
|
|
@@ -120,16 +131,23 @@ class DrawViewController: UIViewController {
|
|
|
make.height.equalTo(view.safeAreaLayoutGuide.snp.height).multipliedBy(0.60)
|
|
|
make.centerX.equalTo(view.safeAreaLayoutGuide.snp.centerX)
|
|
|
}
|
|
|
+
|
|
|
+ remindText.snp.makeConstraints { (make) in
|
|
|
+ make.top.equalTo(generateImage.snp.top).offset(2)
|
|
|
+ make.width.equalTo(generateImage.snp.width)
|
|
|
+ make.height.equalTo(generateImage.snp.height).multipliedBy(0.40)
|
|
|
+ make.centerX.equalTo(generateImage.snp.centerX)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- func translatePrompt(prompt: String, negativePrompt: String) -> (tranPrompt: String, tranNegativePrompt: String){
|
|
|
+ func translatePrompt(prompt: String, negativePrompt: String, completion: @escaping (_ tranPrompt: String, _ tranNegativePrompt: String) -> Void) {
|
|
|
let APP_KEY = "3bb96f14d2af67ec"
|
|
|
let APP_SECRET = "SRQF1jGwAMuYciFK33KfyRGKa7B1x38u"
|
|
|
let q = prompt + "|" + negativePrompt
|
|
|
let salt = UUID().uuidString
|
|
|
let curtime = Int(Date().timeIntervalSince1970)
|
|
|
- print(curtime)
|
|
|
- let signStr = APP_KEY + q + salt + String(curtime) + APP_SECRET
|
|
|
+ let inputQ = q.count <= 20 ? q : String(q.prefix(10)) + String(q.count) + String(q.suffix(10))
|
|
|
+ let signStr = APP_KEY + inputQ + salt + String(curtime) + APP_SECRET
|
|
|
let cryptoSign = signStr.sha256
|
|
|
let paramDic = ["q": q, "from": "auto", "to": "en", "appKey": APP_KEY, "salt": salt, "sign": cryptoSign, "signType": "v3", "curtime": String(curtime)]
|
|
|
let list = NSMutableArray()
|
|
@@ -139,9 +157,16 @@ class DrawViewController: UIViewController {
|
|
|
}
|
|
|
let paramStr = list.componentsJoined(by: "&")
|
|
|
let paramData = "https://openapi.youdao.com/api?" + paramStr
|
|
|
- var addr = paramData.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
|
|
|
- let url = URL(string: addr!)
|
|
|
- var request = URLRequest(url: url!)
|
|
|
+ print(paramData)
|
|
|
+ guard let addr = paramData.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
|
|
|
+ print("error")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ guard let url = URL(string: addr) else {
|
|
|
+ print("error")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var request = URLRequest(url: url)
|
|
|
request.httpMethod = "GET"
|
|
|
|
|
|
var promptValue = ""
|
|
@@ -149,88 +174,119 @@ class DrawViewController: UIViewController {
|
|
|
|
|
|
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
|
|
|
do {
|
|
|
- let jsonData = try JSON(data: data!)
|
|
|
+ guard let unwrapedData = data else {
|
|
|
+ print("error")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let jsonData = try JSON(data: unwrapedData)
|
|
|
let promptData = jsonData["translation"][0].stringValue
|
|
|
print(promptData)
|
|
|
- if String(promptData.first!) == "|" {
|
|
|
- let subStringArr = promptData.split(separator: "| ")
|
|
|
- negativePromotValue = String(subStringArr[0])
|
|
|
+ if String(promptData.first ?? String.Element("")) == "|" {
|
|
|
+ if #available(iOS 16.0, *) {
|
|
|
+ let subStringArr = promptData.split(separator: "|")
|
|
|
+ negativePromotValue = String(subStringArr[0])
|
|
|
+ } else {
|
|
|
+ // Fallback on earlier versions
|
|
|
+ let subStringArr = promptData.components(separatedBy: "|")
|
|
|
+ negativePromotValue = String(subStringArr[0])
|
|
|
+ }
|
|
|
|
|
|
- } else if String(promptData.last!) == "|" {
|
|
|
- let subStringArr = promptData.split(separator: " |")
|
|
|
- promptValue = String(subStringArr[0])
|
|
|
+ } else if String(promptData.last ?? String.Element("")) == "|" {
|
|
|
+ if #available(iOS 16.0, *) {
|
|
|
+ let subStringArr = promptData.split(separator: " |")
|
|
|
+ promptValue = String(subStringArr[0])
|
|
|
+ } else {
|
|
|
+ // Fallback on earlier versions
|
|
|
+ let subStringArr = promptData.components(separatedBy: "|")
|
|
|
+ promptValue = String(subStringArr[0])
|
|
|
+ }
|
|
|
+ } else if promptData == "|"{
|
|
|
+ // do nothing
|
|
|
} else {
|
|
|
- let subStringArr = promptData.split(separator: " | ")
|
|
|
- promptValue = String(subStringArr[0])
|
|
|
- negativePromotValue = String(subStringArr[1])
|
|
|
+ if #available(iOS 16.0, *) {
|
|
|
+ let subStringArr = promptData.split(separator: "|")
|
|
|
+ promptValue = String(subStringArr[0])
|
|
|
+ negativePromotValue = String(subStringArr[1])
|
|
|
+ } else {
|
|
|
+ // Fallback on earlier versions
|
|
|
+ let subStringArr = promptData.components(separatedBy: "|")
|
|
|
+ promptValue = String(subStringArr[0])
|
|
|
+ negativePromotValue = String(subStringArr[1])
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
} catch {}
|
|
|
+ completion(promptValue, negativePromotValue)
|
|
|
}
|
|
|
task.resume()
|
|
|
- return (promptValue, negativePromotValue)
|
|
|
}
|
|
|
|
|
|
@objc func generateAction() {
|
|
|
- let translation = translatePrompt(prompt: promptTextField.text!, negativePrompt: negativePromptTextField.text!)
|
|
|
- generateButton.backgroundColor = .gray
|
|
|
- generateButton.isUserInteractionEnabled = false
|
|
|
-
|
|
|
- print("translation", translation)
|
|
|
- var promptValue = translation.tranPrompt
|
|
|
- var negativePromotValue = translation.tranNegativePrompt
|
|
|
-
|
|
|
- print("Generation: \(promptValue) + \(negativePromotValue)")
|
|
|
-
|
|
|
- prompt = "masterpiece, best quality, " + promptValue
|
|
|
- negativePrompt = "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digits, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, bad feet, " + negativePromotValue
|
|
|
- sessionHash = UUID().uuidString
|
|
|
- painting?.prompt = promptTextField.text!
|
|
|
- painting?.negative_prompt = negativePromptTextField.text!
|
|
|
- painting?.session_hash = sessionHash
|
|
|
- painting?.create_time = Date()
|
|
|
- let url = URL(string: "https://aipaint.hefengyu.org/api/predict/")
|
|
|
- var request = URLRequest(url: url!)
|
|
|
- request.httpMethod = "POST"
|
|
|
- let postData: [String: Any] = ["fn_index":50,"data":[prompt,negativePrompt,"None","None",20,"Euler a",false,false,1,1,7,-1,-1,0,0,0,false,512,512,false,0.7,0,0,"None",false,false,false,"","Seed","","Nothing","",true,false,false,"null","",""],"session_hash":sessionHash]
|
|
|
- let jsonData = try? JSONSerialization.data(withJSONObject: postData, options: [])
|
|
|
- request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
|
- request.httpBody = jsonData
|
|
|
- var imageData: Data?
|
|
|
- let dataTask = URLSession.shared.dataTask(with: request) { (data, request, error) in
|
|
|
- do {
|
|
|
- let json = try? JSON(data: data!)
|
|
|
- let imageAddr = json!["data"][0][0]["name"].stringValue
|
|
|
- let addrProcess = imageAddr.replacingOccurrences(of: "\\", with: "/")
|
|
|
- let imageStr = "https://aipaint.hefengyu.org/file=\(addrProcess)"
|
|
|
- let imageUrl = URL(string: imageStr)
|
|
|
- imageData = try? Data(contentsOf: imageUrl!)
|
|
|
- DispatchQueue.main.async { [self] in
|
|
|
- painting?.image = imageData!
|
|
|
- self.generateImage.image = UIImage(data: imageData!)
|
|
|
- self.generateButton.backgroundColor = .blue
|
|
|
- self.generateButton.isUserInteractionEnabled = true
|
|
|
- if context!.hasChanges {
|
|
|
- do {
|
|
|
- try context?.save()
|
|
|
- print("save success.")
|
|
|
- } catch {}
|
|
|
+ let promptText = promptTextField.text ?? ""
|
|
|
+ let negativePromptText = negativePromptTextField.text ?? ""
|
|
|
+
|
|
|
+ translatePrompt(prompt: promptTextField.text!, negativePrompt: negativePromptTextField.text!) { [self] promptValue, negativePromotValue in
|
|
|
+
|
|
|
+ prompt = "masterpiece, best quality, " + promptValue
|
|
|
+ negativePrompt = "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digits, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, bad feet, " + negativePromotValue
|
|
|
+ sessionHash = UUID().uuidString
|
|
|
+ guard let unwrapedDelegate = delegate else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ context = unwrapedDelegate.persistentContainer.viewContext
|
|
|
+ painting = NSEntityDescription.insertNewObject(forEntityName: "Painting", into: context!) as? Painting
|
|
|
+ painting?.prompt = promptText
|
|
|
+ painting?.negative_prompt = negativePromptText
|
|
|
+ painting?.session_hash = sessionHash
|
|
|
+ painting?.create_time = Date()
|
|
|
+ guard let url = URL(string: "https://aipaint.hefengyu.org/api/predict/") else {
|
|
|
+ print("error")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var request = URLRequest(url: url)
|
|
|
+ request.httpMethod = "POST"
|
|
|
+ let postData: [String: Any] = ["fn_index":50, "data":[prompt,negativePrompt,"None","None",20,"Euler a",false,false,1,1,7,-1,-1,0,0,0,false,512,512,false,0.7,0,0,"None",false,false,false,"","Seed","","Nothing","",true,false,false,"null","",""], "session_hash":sessionHash]
|
|
|
+ let jsonData = try? JSONSerialization.data(withJSONObject: postData, options: [])
|
|
|
+ request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
|
+ request.httpBody = jsonData
|
|
|
+ let dataTask = URLSession.shared.dataTask(with: request) { (data, request, error) in
|
|
|
+ do {
|
|
|
+ guard let data = data else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ guard let json = try? JSON(data: data) else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let imageAddr = json["data"][0][0]["name"].stringValue
|
|
|
+ let addrProcess = imageAddr.replacingOccurrences(of: "\\", with: "/")
|
|
|
+ let imageStr = "https://aipaint.hefengyu.org/file=\(addrProcess)"
|
|
|
+ guard let imageUrl = URL(string: imageStr) else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ guard let imageData = try? Data(contentsOf: imageUrl) else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ DispatchQueue.main.async { [self] in
|
|
|
+ painting?.image = imageData
|
|
|
+ self.generateImage.image = UIImage(data: imageData)
|
|
|
+ self.generateButton.backgroundColor = .blue
|
|
|
+ self.generateButton.isUserInteractionEnabled = true
|
|
|
+ saveContext()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ dataTask.resume()
|
|
|
}
|
|
|
-// let processURL = URL(string: "https://aipaint.hefengyu.org/api/predict/")
|
|
|
-// let processTask = URLSession.shared.dataTask(with: <#T##URLRequest#>)
|
|
|
- dataTask.resume()
|
|
|
+ generateButton.backgroundColor = .gray
|
|
|
+ generateButton.isUserInteractionEnabled = false
|
|
|
}
|
|
|
|
|
|
@objc func saveImageToPhotos() {
|
|
|
if (longPress!.state == .began) {
|
|
|
- // do something
|
|
|
- print("nice")
|
|
|
guard let img = generateImage.image else {
|
|
|
+ print("error")
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
switch PHPhotoLibrary.authorizationStatus() {
|
|
|
case .authorized:
|
|
|
saveImg(image: img)
|
|
@@ -258,6 +314,15 @@ class DrawViewController: UIViewController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ func saveContext() {
|
|
|
+ if context!.hasChanges {
|
|
|
+ do {
|
|
|
+ try context?.save()
|
|
|
+ print("save success.")
|
|
|
+ } catch {}
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
func saveImg(image: UIImage) {
|
|
|
PHPhotoLibrary.shared().performChanges({
|
|
|
PHAssetChangeRequest.creationRequestForAsset(from: image)
|