TSAIPhotoRemoveVC.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. //
  2. // TSAIRemovePhotoBgVC.swift
  3. // TSLiveWallpaper
  4. //
  5. // Created by 100Years on 2025/7/21.
  6. //
  7. import Kingfisher
  8. class TSAIRemovePhotoBgVC: TSBaseVC {
  9. var originalImage:UIImage
  10. init(image: UIImage) {
  11. self.originalImage = image
  12. super.init()
  13. }
  14. @MainActor required init?(coder: NSCoder) {
  15. fatalError("init(coder:) has not been implemented")
  16. }
  17. lazy var photoPickerManager: TSPhotoPickerManager = TSPhotoPickerManager(viewController: self)
  18. var isSavePhotoMark:Bool = false
  19. var isNeedSavePhoto:Bool {
  20. if isSavePhotoMark == false,let _ = infoModel {
  21. return true
  22. }
  23. return false
  24. }
  25. var infoModel:TSActionInfoModel?{
  26. didSet{
  27. updateImageView()
  28. }
  29. }
  30. var operation:TSGenerateBaseOperation?
  31. var uuidString:String = UUID().uuidString
  32. var progressState = TSProgressState.none
  33. lazy var shareBtn: TSVerticalButton = {
  34. let shareBtn = TSVerticalButton()
  35. shareBtn.setUpButton(title: "Share".localized,
  36. image: .share,
  37. font: .font(name:.ZillaSlab,size: 14,weight: .medium),
  38. titleColor: .white,
  39. autoMirrored: false){ [weak self] in
  40. guard let self = self else { return }
  41. clickShare()
  42. }
  43. shareBtn.contentEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
  44. shareBtn.titleLabel?.layer.shadowColor = UIColor.black.cgColor
  45. shareBtn.titleLabel?.layer.shadowOffset = CGSize(width: 0, height: 2)
  46. shareBtn.titleLabel?.layer.shadowRadius = 3
  47. shareBtn.titleLabel?.layer.shadowOpacity = 0.4
  48. shareBtn.titleLabel?.layer.masksToBounds = false
  49. return shareBtn
  50. }()
  51. lazy var saveBtn: UIButton = {
  52. let saveBtn = kCreateNormalSubmitBtn(title: "Save".localized) { [weak self] in
  53. guard let self = self else { return }
  54. clickSaveBtn()
  55. }
  56. kSetBtnVipIcon(btn: saveBtn, show: true)
  57. return saveBtn
  58. }()
  59. lazy var removeView: TSAIPhotoRemoveBgView = {
  60. let removeView = TSAIPhotoRemoveBgView(targetVC: self)
  61. removeView.setFrontImage(image: originalImage)
  62. // removeView.clickImageViewBlock = { [weak self] in
  63. // guard let self = self else { return }
  64. // clickNavRight()
  65. // }
  66. return removeView
  67. }()
  68. lazy var generateInView : TSGeneratorView = {
  69. let generateInView = TSGeneratorView()
  70. generateInView.isUploadImage = false
  71. generateInView.backgroundColor = .black.withAlphaComponent(0.95)
  72. generateInView.animationView.setText(time: String(format: "~ %d mins".localized, 1), info: "Lots of people are processing images right now, so this might take a bit.".localized)
  73. generateInView.clickErrorBlock = { [weak self] style in
  74. guard let self = self else { return }
  75. switch style {
  76. case .netWorkError:
  77. clickRegenerateBtn()
  78. default:
  79. self.cancelDidmiss()
  80. break
  81. }
  82. }
  83. // generateInView.clickBackstageBlock = { [weak self] in
  84. // guard let self = self else { return }
  85. // clickBackstageBtn()
  86. // }
  87. generateInView.clickCloseBlock = { [weak self] in
  88. guard let self = self else { return }
  89. closePage()
  90. }
  91. return generateInView
  92. }()
  93. //重新生成
  94. @objc func clickRegenerateBtn(){
  95. if kPurchaseBusiness.kJudgeVipFreeType(vipFreeNumType: .generalRemoveBg){ return }//判断 vip
  96. generatorOperation()
  97. }
  98. func updateImageView(){
  99. guard let infoModel = self.infoModel else { return }
  100. removeView.setFrontImageURLString(urlString: infoModel.response.resultUrl)
  101. }
  102. func closePage() {
  103. if progressState.isResult {
  104. if isNeedSavePhoto{
  105. TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
  106. message: "You haven't saved the photo yet. Are you sure to quit?".localized,
  107. messageColor: .white,
  108. messageFont: .systemFont(ofSize: 16),
  109. cancelTitle: "Quit".localized,
  110. cancelColor: .white,
  111. confirmTitle: "Save".localized,
  112. confirmColor: .themeColor,
  113. cancelAction: { [weak self] in
  114. guard let self = self else { return }
  115. print("用户点击了Leave")
  116. cancelDidmiss()
  117. },
  118. confirmAction: { [weak self] in
  119. guard let self = self else { return }
  120. print("用户点击了Stay")
  121. clickSaveBtn()
  122. }
  123. ))
  124. }else{
  125. cancelDidmiss()
  126. }
  127. }else{
  128. TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
  129. message: "As you leave, your task will be interrupted and no result.".localized,
  130. messageColor: .white,
  131. messageFont: .systemFont(ofSize: 16),
  132. cancelTitle: "Leave".localized,
  133. cancelColor: .white,
  134. confirmTitle: "Wait".localized,
  135. confirmColor: .themeColor,
  136. cancelAction: { [weak self] in
  137. guard let self = self else { return }
  138. print("用户点击了Leave")
  139. if let model = infoModel{
  140. TSRMShared.aiListDB.deleteListModel(id: model.id)
  141. NotificationCenter.default.post(name: .kAIPhotoDataChanged, object: nil)
  142. }
  143. cancelDidmiss()
  144. },
  145. confirmAction: {
  146. print("用户点击了Stay")
  147. }
  148. ))
  149. }
  150. }
  151. func cancelDidmiss(){
  152. operation?.cancel()
  153. self.pop()
  154. }
  155. override func createView() {
  156. setPageTitle("Remove Background".localized)
  157. // _ = setNavigationItem("", imageName: "replace_photo", direction: .right, action: #selector(clickNavRight))
  158. contentView.addSubview(removeView)
  159. removeView.snp.makeConstraints { make in
  160. make.edges.equalToSuperview()
  161. }
  162. let bottomBtnTop:CGFloat = -8-k_Height_safeAreaInsetsBottom()
  163. contentView.addSubview(shareBtn)
  164. shareBtn.snp.makeConstraints { make in
  165. make.leading.equalTo(16)
  166. make.width.equalTo(shareBtn.intrinsicContentSize.width)
  167. make.height.equalTo(48)
  168. make.bottom.equalTo(bottomBtnTop)
  169. }
  170. contentView.addSubview(saveBtn)
  171. saveBtn.snp.makeConstraints { make in
  172. make.leading.equalTo(shareBtn.snp.trailing).offset(40)
  173. make.trailing.equalTo(-16.0)
  174. make.height.equalTo(48)
  175. make.bottom.equalTo(bottomBtnTop)
  176. }
  177. view.addSubview(generateInView)
  178. generateInView.snp.makeConstraints { make in
  179. make.edges.equalToSuperview()
  180. }
  181. }
  182. override func dealThings() {
  183. self.uuidString = UUID().uuidString
  184. generatorOperation()
  185. }
  186. func generatorOperation() {
  187. generatorNew()
  188. }
  189. }
  190. extension TSAIRemovePhotoBgVC {
  191. //分享功能
  192. @objc func clickShare(){
  193. if kJudgeVip(externalBool: true, vc: self){ return }
  194. removeView.compositeImages { [weak self] image in
  195. guard let self = self else { return }
  196. if let image = image {
  197. kShareContent(target: self, anyData: image)
  198. isSavePhotoMark = true
  199. if let resultUrl = self.infoModel?.response.resultUrl{
  200. // TSImageStoreTool.storeImage(image: image, urlString: resultUrl)
  201. TSImagePhotoDiskTool.saveDiskImage(image: image, urlString: resultUrl)
  202. }
  203. }
  204. }
  205. }
  206. // @objc func clickNavRight() {
  207. // if kPurchaseBusiness.kJudgeVipFreeType(vipFreeNumType: .generalRemoveBg){ return }//判断 vip
  208. // photoPickerManager.pickPhoto(maxSelected: 1) { [weak self] images in
  209. // guard let self = self else { return }
  210. // if let image = images.first {
  211. // originalImage = image
  212. // removeView.setFrontImage(image: originalImage)
  213. // }
  214. // self.photoPickerManager.dismissPageVC()
  215. // }
  216. // }
  217. //保存功能
  218. @objc func clickSaveBtn(){
  219. if kJudgeVip(externalBool: true, vc: self){ return }
  220. removeView.compositeImages { [weak self] image in
  221. if let image = image {
  222. PhotoManagerShared.saveImageToAlbum(image) { [weak self] success, error in
  223. guard let self = self else { return }
  224. if success {
  225. isSavePhotoMark = true
  226. kSaveSuccesswShared.show(atView:self.view)
  227. if let resultUrl = self.infoModel?.response.resultUrl{
  228. // TSImageStoreTool.storeImage(image: image, urlString: resultUrl)
  229. TSImagePhotoDiskTool.saveDiskImage(image: image, urlString: resultUrl)
  230. }
  231. }else{
  232. debugPrint(error)
  233. }
  234. }
  235. }
  236. }
  237. }
  238. }
  239. extension TSAIRemovePhotoBgVC{
  240. func generatorNew() {
  241. let operation:TSGenerateBasePhotoOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: self.uuidString)
  242. self.operation = operation
  243. operation.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self] (state,model) in
  244. guard let self = self else { return }
  245. self.upDateView(state: state, model: model)
  246. }.store(in: &cancellable)
  247. let generatorModel = TSAIListPhotoGeneratorModel(upLoadImage: originalImage, generatorStyle: .removeBg)
  248. operation.uploadImage(generateStyleModel: generatorModel) { [weak self] actionInfoModel in
  249. guard let self = self else { return }
  250. guard let oldModel = actionInfoModel else {return}
  251. generatorCreatRing(oldModel: oldModel)
  252. }
  253. }
  254. func generatorCreatRing(oldModel:TSActionInfoModel) {
  255. let operation:TSGenerateBasePhotoOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: self.uuidString)
  256. self.operation = operation
  257. operation.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self] (state,model) in
  258. guard let self = self else { return }
  259. self.upDateView(state: state, model: model)
  260. }.store(in: &cancellable)
  261. operation.creatImage(oldModel: oldModel){ [weak self] success in
  262. guard let self = self else { return }
  263. if success {
  264. generateInView.setBackgroundGenerateBtnHidden(true)
  265. }
  266. }
  267. }
  268. }
  269. extension TSAIRemovePhotoBgVC {
  270. func upDateView(state:TSProgressState,model:TSActionInfoModel?){
  271. progressState = state
  272. switch state {
  273. case .failed(let errorStr,let code):
  274. showError(text: errorStr,code:code)
  275. case .success:
  276. if let model = model {
  277. showSuccess(model: model)
  278. }else{
  279. showError(text: "")
  280. }
  281. case .progressString(let string):
  282. showProgress(text: string)
  283. default:
  284. showLoading()
  285. }
  286. }
  287. func showProgress(text:String) {
  288. generateInView.updateShowProgress(text: text)
  289. }
  290. func showLoading(){
  291. generateInView.updateShowLoading(text: "Processing".localized + " " + kPercentlocalized(0))
  292. }
  293. func showError(text:String,code:Int = 0){
  294. generateInView.updateShowError(text: text,code: code)
  295. }
  296. func showSuccess(model:TSActionInfoModel){
  297. generateInView.updateShowSuccess()
  298. infoModel = model
  299. if let model = infoModel {
  300. // complete(model)
  301. }
  302. }
  303. }