TSAIChangeEmoteVM.swift 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. //
  2. // TSAIChangeEmoteVM.swift
  3. // AIEmoji
  4. //
  5. // Created by 100Years on 2025/4/10.
  6. //
  7. import ObjectMapper
  8. import Alamofire
  9. class TSAIChangeEmoteVM {
  10. //###################################### 样式选择 ######################################
  11. var selectedStyleIndex:Int = 1
  12. lazy var selectStyleModels: [TSGenerateStyleModel] = {
  13. var selectStyleModels = [TSGenerateStyleModel]()
  14. if let dataArray = Mapper<TSGenerateStyleModel>().mapArray(JSONfile: jsonName){
  15. selectStyleModels = dataArray
  16. if let model = dataArray.safeObj(At: selectedStyleIndex) {
  17. selectStyleModel = model //加上默认的选择
  18. }
  19. }
  20. return selectStyleModels
  21. }()
  22. var selectStyleModel:TSGenerateStyleModel?
  23. var isSavePhotoMark:Bool = false
  24. var isNeedSavePhoto:Bool {
  25. if let selectStyleModel = selectStyleModel,
  26. selectStyleModel.clickType == 1{
  27. return false
  28. }
  29. if isSavePhotoMark == false{
  30. for model in selectStyleModels {
  31. if let _ = model.actionInfoModel {
  32. return true
  33. }
  34. }
  35. }
  36. return false
  37. }
  38. //###################################### 生成图片 ######################################
  39. var uploadRequest:Request?
  40. var creatRequest:Request?
  41. var queryRequest:Request?
  42. var stopNetwork = false
  43. @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil)
  44. var aiText:String = ""
  45. var generatingProgress = 0
  46. var upLoadImage:UIImage?{
  47. didSet{
  48. imageUrl = nil
  49. isSavePhotoMark = false
  50. for model in selectStyleModels {
  51. model.actionInfoModel = nil
  52. }
  53. }
  54. }
  55. var imageUrl:String?
  56. var style:TSAIChangeEmoteVC.Style
  57. init(style: TSAIChangeEmoteVC.Style) {
  58. self.style = style
  59. }
  60. }
  61. extension TSAIChangeEmoteVM {
  62. func creatImage() {
  63. guard let imageUrl = imageUrl else { return }
  64. guard let selectStyleModel = selectStyleModel else { return }
  65. generatingProgress = 0
  66. stopNetwork = false
  67. stateDatauPblished = (.start,nil)
  68. stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
  69. var urlType:TSNeURLType = .changeEmotion
  70. var postDict:[String:Any] = [:]
  71. switch style {
  72. case .changeEmote:
  73. urlType = .changeEmotion
  74. postDict = ["emotionType":selectStyleModel.style,
  75. "imageUrl":imageUrl,
  76. "device":getUserInfoJsonString()]
  77. case .changehairColor:
  78. urlType = .imageRewrite
  79. postDict = ["prompt":selectStyleModel.prompt,
  80. "imageUrl":imageUrl,
  81. "device":getUserInfoJsonString()]
  82. case .changehair:
  83. urlType = .changeHair
  84. postDict = ["hairType":Int(selectStyleModel.style) ?? 101,
  85. "imageUrl":imageUrl,
  86. "device":getUserInfoJsonString()]
  87. }
  88. creatRequest = TSNetworkShared.post(urlType: urlType,parameters:postDict) { [weak self] data,error in
  89. guard let self = self else { return }
  90. if let dataDict = data as? [String:Any] ,
  91. dataDict.safeInt(forKey: "code") == 200,
  92. let actionId = dataDict["actionId"] as? Int{
  93. if stopNetwork == false {
  94. self.getActionInfo(action_id:actionId)
  95. }
  96. }else{
  97. self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
  98. }
  99. }
  100. }
  101. func getActionInfo(action_id:Int){
  102. queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
  103. guard let self = self else { return }
  104. if let result = kNetWorkResultSuccess(data: data) {
  105. if let genmojiModel = TSActionInfoModel(JSON: result) {
  106. switch genmojiModel.actionStatus {
  107. case .success:
  108. if let url = URL(string:genmojiModel.response.resultUrl) {
  109. UIImageView.downloadImageWithProgress(urlString: genmojiModel.response.resultUrl) { [weak self] progress in
  110. guard let self = self else { return }
  111. let progressInt = Int(progress*10.0)
  112. let progressString = "Changing".localized + " \(90 + progressInt)%"
  113. stateDatauPblished = (.progressString(progressString),nil)
  114. dePrint("生成后图片下载进度 \(progress)")
  115. } completion: {[weak self] image in
  116. guard let self = self else { return }
  117. self.stateDatauPblished = (.success(nil),genmojiModel)
  118. self.selectStyleModel?.actionInfoModel = genmojiModel
  119. generatingProgress = 0
  120. }
  121. }else{
  122. self.stateDatauPblished = (.success(nil),genmojiModel)
  123. self.selectStyleModel?.actionInfoModel = genmojiModel
  124. generatingProgress = 0
  125. }
  126. case .failed:
  127. self.stateDatauPblished = (.failed(kNetWorkMessage(data: data) ?? ""),nil)
  128. generatingProgress = 0
  129. default:
  130. stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),nil)
  131. if stopNetwork == false {
  132. kDelayOnMainThread(1.0) {
  133. self.getActionInfo(action_id: action_id)
  134. }
  135. }
  136. }
  137. }
  138. }else{
  139. self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
  140. }
  141. }
  142. }
  143. func cancelAllRequest(){
  144. creatRequest?.cancel()
  145. queryRequest?.cancel()
  146. stopNetwork = true
  147. }
  148. func generating(progress:Float) -> String {
  149. let progress = progress*(0.9) // 预留 10% 进度给图片下载
  150. //Generating 0%-100%
  151. var progressInt = Int(progress*100)
  152. if progressInt > 99 {
  153. progressInt = 99
  154. }
  155. generatingProgress = progressInt
  156. return "Changing".localized + " \(progressInt)%"
  157. }
  158. // //模拟数据
  159. // func uploadAndCreatImage() {
  160. //
  161. // stateDatauPblished = (.start,nil)
  162. // stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
  163. //
  164. // kDelayOnMainThread(0.2) {
  165. // self.stateDatauPblished = (.progressString(self.generating(progress: 0.2)),nil)
  166. // }
  167. //
  168. // kDelayOnMainThread(0.5) {
  169. // self.stateDatauPblished = (.progressString(self.generating(progress: 0.5)),nil)
  170. // }
  171. //
  172. // kDelayOnMainThread(0.8) {
  173. // self.stateDatauPblished = (.progressString(self.generating(progress: 0.8)),nil)
  174. // }
  175. //
  176. //
  177. // kDelayOnMainThread(2.0) {
  178. // if kRandomBool() {
  179. // let infoModel = TSActionInfoModel(JSON:actionInfoDictPoster )
  180. // self.stateDatauPblished = (.success(nil),infoModel)
  181. // }else{
  182. // self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
  183. // }
  184. // }
  185. //
  186. // }
  187. func uploadAndCreatImage() {
  188. if let model = selectStyleModel?.actionInfoModel {
  189. self.stateDatauPblished = (.success(nil),model)
  190. return
  191. }
  192. if let imageUrl = imageUrl,imageUrl.contains("http") {
  193. creatImage()
  194. return
  195. }
  196. guard let upLoadImage = upLoadImage else { return }
  197. stopNetwork = false
  198. stateDatauPblished = (.start,nil)
  199. stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)),nil)
  200. uploadRequest = TSNetworkShared.uploadImage(upLoadImage: upLoadImage, maxKb: imageMaxKb) { [weak self] progress in
  201. guard let self = self else { return }
  202. if generatingProgress == 0 {
  203. stateDatauPblished = (.progressString(uploadingPhoto(progress: progress)),nil)
  204. }
  205. } completion: { [weak self] data, error in
  206. guard let self = self else { return }
  207. if let error = error {
  208. imageUrl = nil
  209. self.stateDatauPblished = (.failed(error.localizedDescription),nil)
  210. }else{
  211. if let string = data as? String {
  212. imageUrl = string
  213. creatImage()
  214. }
  215. }
  216. }
  217. }
  218. var imageMaxKb:Int{
  219. switch style {
  220. case .changeEmote:
  221. return 10*1024
  222. case .changehairColor:
  223. return 10*1024
  224. case .changehair:
  225. return 10*1024
  226. }
  227. }
  228. func uploadingPhoto(progress:Float) -> String {
  229. //Uploading Photo 0%-100%
  230. var progressInt = Int(progress*100)
  231. if progressInt > 99 {
  232. progressInt = 99
  233. }
  234. return "Uploading Photo".localized + " \(progressInt)%"
  235. }
  236. }
  237. extension TSAIChangeEmoteVM {
  238. var jsonName:String{
  239. switch style {
  240. case .changeEmote:
  241. return "ai_change_emote_style.json"
  242. case .changehairColor:
  243. return "ai_change_hair_color_style.json"
  244. case .changehair:
  245. return "ai_change_hair_style.json"
  246. }
  247. }
  248. }