Commit bbc7d200 authored by netyouli's avatar netyouli

添加图生图功能

parent 0618b3ec
...@@ -30,7 +30,7 @@ class AIDrawImageResultController extends GetxController { ...@@ -30,7 +30,7 @@ class AIDrawImageResultController extends GetxController {
var styleName = "".obs; var styleName = "".obs;
var text = "".obs; var text = "".obs;
var enText = ""; var enText = "";
var imageUrl = "".obs; var resultImageUrl = "".obs;
var progress = 0.obs; var progress = 0.obs;
var showProgressView = false.obs; var showProgressView = false.obs;
var loseTime = "0.0s".obs; var loseTime = "0.0s".obs;
...@@ -171,7 +171,13 @@ class AIDrawImageResultController extends GetxController { ...@@ -171,7 +171,13 @@ class AIDrawImageResultController extends GetxController {
makeDrawImage() async { makeDrawImage() async {
progress.value = 0; progress.value = 0;
final question = '$enText --ar $ratio$s'; final imageUrl = imageUrls.first;
var question = "";
if (imageUrl.isNotEmpty) {
question = '$imageUrl $enText --iw 2 --ar $ratio$s';
} else {
question = '$enText --ar $ratio$s';
}
Logger.debugPrint("question = $question"); Logger.debugPrint("question = $question");
EasyLoading.show(status: "AI正在生成中..."); EasyLoading.show(status: "AI正在生成中...");
try { try {
...@@ -230,17 +236,17 @@ class AIDrawImageResultController extends GetxController { ...@@ -230,17 +236,17 @@ class AIDrawImageResultController extends GetxController {
} }
final progressBase64 = model.progressBase64?.replaceAll("data:image/png;base64,", "") ?? ""; final progressBase64 = model.progressBase64?.replaceAll("data:image/png;base64,", "") ?? "";
if (model.response?.imageUrl != null) { if (model.response?.imageUrl != null) {
imageUrl.value = model.response?.imageUrl ?? "" ; resultImageUrl.value = model.response?.imageUrl ?? "" ;
} else if (model.progressImageUrl != null) { } else if (model.progressImageUrl != null) {
imageUrl.value = model.progressImageUrl ?? ""; resultImageUrl.value = model.progressImageUrl ?? "";
} }
if (progressBase64.isNotEmpty) { if (progressBase64.isNotEmpty) {
final decode = base64Decode(progressBase64.replaceAll('\n', '')); final decode = base64Decode(progressBase64.replaceAll('\n', ''));
placehoderImageData = imageData.value ?? decode; placehoderImageData = imageData.value ?? decode;
imageData.value = decode; imageData.value = decode;
} else { } else {
if (imageUrl.value.isNotEmpty) { if (resultImageUrl.value.isNotEmpty) {
loadImage(imageUrl.value, model.progress ?? 0); loadImage(resultImageUrl.value, model.progress ?? 0);
} }
} }
// final first = model.response?.buttons?.first ?? ""; // final first = model.response?.buttons?.first ?? "";
......
...@@ -192,7 +192,7 @@ class AIDrawImageResultPage extends GetView<AIDrawImageResultController> { ...@@ -192,7 +192,7 @@ class AIDrawImageResultPage extends GetView<AIDrawImageResultController> {
children: [ children: [
InkWell( InkWell(
onTap: () { onTap: () {
controller.saveNetworkImage(controller.imageUrl.value); controller.saveNetworkImage(controller.resultImageUrl.value);
}, },
child: Container( child: Container(
width: 150, width: 150,
......
...@@ -6,6 +6,7 @@ import 'package:chart/common/apis/apis.dart'; ...@@ -6,6 +6,7 @@ import 'package:chart/common/apis/apis.dart';
import 'package:chart/common/utils/utils.dart'; import 'package:chart/common/utils/utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart'; import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart';
...@@ -19,6 +20,7 @@ import 'model.dart'; ...@@ -19,6 +20,7 @@ import 'model.dart';
class AIDrawImageController extends GetxController { class AIDrawImageController extends GetxController {
late TabController tabController; late TabController tabController;
late TabController categoryController; late TabController categoryController;
ScrollController textToImageController = ScrollController(initialScrollOffset: 0);
var model = AIDrawTextToImageModel(); var model = AIDrawTextToImageModel();
var ratio = "9:16".obs; var ratio = "9:16".obs;
var descriptionText = "".obs; var descriptionText = "".obs;
...@@ -28,7 +30,8 @@ class AIDrawImageController extends GetxController { ...@@ -28,7 +30,8 @@ class AIDrawImageController extends GetxController {
TextEditingController textController = TextEditingController(text: ""); TextEditingController textController = TextEditingController(text: "");
Offset startPoint = const Offset(0, 0); Offset startPoint = const Offset(0, 0);
RxList<AIDrawDescriptiveItem> randomDescriptionItems = RxList<AIDrawDescriptiveItem>(); RxList<AIDrawDescriptiveItem> randomDescriptionItems = RxList<AIDrawDescriptiveItem>();
RxList<XFile> assets = RxList<XFile>(); RxList<XFile> blendAssets = RxList<XFile>();
RxList<XFile> textAssets = RxList<XFile>();
var sizePictures = [ var sizePictures = [
AIDrawSizePictrue(name: "手机壁纸", ratio: "9:16", imageUrl: "assets/images/v_iphone.png"), AIDrawSizePictrue(name: "手机壁纸", ratio: "9:16", imageUrl: "assets/images/v_iphone.png"),
AIDrawSizePictrue(name: "电脑壁纸", ratio: "16:9", imageUrl: "assets/images/h_iphone.png"), AIDrawSizePictrue(name: "电脑壁纸", ratio: "16:9", imageUrl: "assets/images/h_iphone.png"),
...@@ -59,7 +62,8 @@ class AIDrawImageController extends GetxController { ...@@ -59,7 +62,8 @@ class AIDrawImageController extends GetxController {
]; ];
var textCount = 0.obs; var textCount = 0.obs;
var uploadImageUrls = List.generate(0, (index) => ""); var uploadBlendImageUrls = List<String>.generate(0, (index) => "");
var uploadTextImageUrls = List<String>.generate(0, (index) => "");
@override @override
void onInit() { void onInit() {
...@@ -73,6 +77,16 @@ class AIDrawImageController extends GetxController { ...@@ -73,6 +77,16 @@ class AIDrawImageController extends GetxController {
descriptionText.value = textController.text; descriptionText.value = textController.text;
} }
}); });
KeyboardVisibilityController().onChange.listen((bool visible) {
if (tabController.index == 0) {
if (visible) {
textToImageController.animateTo(140, duration: const Duration(milliseconds: 100), curve: Curves.linear);
} else {
textToImageController.animateTo(0, duration: const Duration(milliseconds: 100), curve: Curves.linear);
}
}
});
} }
@override @override
...@@ -95,12 +109,17 @@ class AIDrawImageController extends GetxController { ...@@ -95,12 +109,17 @@ class AIDrawImageController extends GetxController {
textController.setText(model.descriptives[randomIndex].description); textController.setText(model.descriptives[randomIndex].description);
} }
clearSelectedImage() { clearBlendSelectedImage() {
assets.value = []; blendAssets.value = [];
uploadImageUrls.clear(); uploadBlendImageUrls.clear();
} }
selectImageUpload(ImageSource source) async { clearTextSelectedImage() {
textAssets.clear();
uploadTextImageUrls.clear();
}
selectBlendImageUpload(ImageSource source) async {
List<XFile>? images; List<XFile>? images;
if (source == ImageSource.camera) { if (source == ImageSource.camera) {
final image = await ImagePicker().pickImage(source: ImageSource.camera); final image = await ImagePicker().pickImage(source: ImageSource.camera);
...@@ -115,7 +134,7 @@ class AIDrawImageController extends GetxController { ...@@ -115,7 +134,7 @@ class AIDrawImageController extends GetxController {
EasyLoading.showError("请选择1-5张图片"); EasyLoading.showError("请选择1-5张图片");
} else { } else {
for (var image in images) { for (var image in images) {
assets.add(image); blendAssets.add(image);
} }
} }
EasyLoading.show( EasyLoading.show(
...@@ -140,14 +159,46 @@ class AIDrawImageController extends GetxController { ...@@ -140,14 +159,46 @@ class AIDrawImageController extends GetxController {
if (i == count - 1) { if (i == count - 1) {
EasyLoading.dismiss(); EasyLoading.dismiss();
} }
uploadImageUrls.add(res.data ?? ""); uploadBlendImageUrls.add(res.data ?? "");
}
}
} }
} }
selectTextImageUpload(ImageSource source) async {
XFile? image;
if (source == ImageSource.camera) {
image = await ImagePicker().pickImage(source: ImageSource.camera);
} else {
image = await ImagePicker().pickImage(source: ImageSource.gallery);
}
if (image == null) return null;
textAssets.add(image);
EasyLoading.show(
status: "正在上传,请稍后",
dismissOnTap: false,
maskType: EasyLoadingMaskType.none,
indicator: LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white,
size: 30,
));
final res = await NewsAPI.uploadFile([File(image.path)]);
if (res.status == 401) {
EasyLoading.showInfo('您还未登录,请登录后体验功能。');
Get.toNamed(AppRoutes.SIGN_IN);
// state.isLoading = false;
} else {
if (res.data == null) {
EasyLoading.showToast(res.message ?? "未知错误");
} else {
EasyLoading.dismiss();
uploadTextImageUrls.add(res.data ?? "");
}
} }
} }
toImageMarkDrawImage() async { toImageMarkDrawImage() async {
if (uploadImageUrls.length < 2 || uploadImageUrls.length > 5) { if (uploadBlendImageUrls.length < 2 || uploadBlendImageUrls.length > 5) {
EasyLoading.showError("请选择2-5张图片"); EasyLoading.showError("请选择2-5张图片");
return; return;
} }
...@@ -170,12 +221,12 @@ class AIDrawImageController extends GetxController { ...@@ -170,12 +221,12 @@ class AIDrawImageController extends GetxController {
arguments: { arguments: {
"opearter": "imageToImage", "opearter": "imageToImage",
"conversionId": conversionId, "conversionId": conversionId,
"imageUrls": List<String>.from(uploadImageUrls), "imageUrls": List<String>.from(uploadBlendImageUrls),
"ratio": ratio.value, "ratio": ratio.value,
"s": s, "s": s,
"styleName": styleName.value "styleName": styleName.value
}); });
clearSelectedImage(); clearBlendSelectedImage();
} }
} }
...@@ -204,12 +255,14 @@ class AIDrawImageController extends GetxController { ...@@ -204,12 +255,14 @@ class AIDrawImageController extends GetxController {
arguments: { arguments: {
"opearter": "textToImage", "opearter": "textToImage",
"conversionId": conversionId, "conversionId": conversionId,
"imageUrls": List<String>.from(uploadTextImageUrls),
"enText": transformModel.transResult?.first.dst ?? textController.text, "enText": transformModel.transResult?.first.dst ?? textController.text,
"text": textController.text, "text": textController.text,
"ratio": ratio.value, "ratio": ratio.value,
"s": s, "s": s,
"styleName": styleName.value "styleName": styleName.value
}); });
clearTextSelectedImage();
} }
} }
......
...@@ -25,7 +25,7 @@ import 'controller.dart'; ...@@ -25,7 +25,7 @@ import 'controller.dart';
children: [ children: [
InkWell( InkWell(
onTap: () { onTap: () {
controller.selectImageUpload(ImageSource.camera); controller.selectBlendImageUpload(ImageSource.camera);
Get.back(); Get.back();
}, },
child: Container( child: Container(
...@@ -42,7 +42,7 @@ import 'controller.dart'; ...@@ -42,7 +42,7 @@ import 'controller.dart';
SizedBox(height: 10,), SizedBox(height: 10,),
InkWell( InkWell(
onTap: () { onTap: () {
controller.selectImageUpload(ImageSource.gallery); controller.selectBlendImageUpload(ImageSource.gallery);
Get.back(); Get.back();
}, },
child: Container( child: Container(
...@@ -65,10 +65,10 @@ import 'controller.dart'; ...@@ -65,10 +65,10 @@ import 'controller.dart';
Widget makeShowAssetImageView(double width) { Widget makeShowAssetImageView(double width) {
final controller = Get.find<AIDrawImageController>(); final controller = Get.find<AIDrawImageController>();
final count = controller.assets.length < 5 ? controller.assets.length + 1 : controller.assets.length; final count = controller.blendAssets.length < 5 ? controller.blendAssets.length + 1 : controller.blendAssets.length;
final children = List<Widget>.generate(count, (index) { final children = List<Widget>.generate(count, (index) {
if (index < controller.assets.length) { if (index < controller.blendAssets.length) {
final element = controller.assets[index]; final element = controller.blendAssets[index];
return Image.file(File(element.path), width: (width - 20) / 5.0, height: 160, fit: BoxFit.contain,); return Image.file(File(element.path), width: (width - 20) / 5.0, height: 160, fit: BoxFit.contain,);
} }
return Container( return Container(
...@@ -121,13 +121,13 @@ import 'controller.dart'; ...@@ -121,13 +121,13 @@ import 'controller.dart';
return Stack( return Stack(
children: [ children: [
Obx(() => Visibility( Obx(() => Visibility(
visible: controller.assets.isNotEmpty, visible: controller.blendAssets.isNotEmpty,
child: Positioned( child: Positioned(
right: 0, right: 0,
top: 0, top: 0,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
controller.clearSelectedImage(); controller.clearBlendSelectedImage();
}, },
child: Image.asset("assets/images/清空图片.png", width: 30, height: 30,), child: Image.asset("assets/images/清空图片.png", width: 30, height: 30,),
) )
...@@ -149,7 +149,7 @@ import 'controller.dart'; ...@@ -149,7 +149,7 @@ import 'controller.dart';
child: Obx(() => Stack( child: Obx(() => Stack(
children: [ children: [
Visibility( Visibility(
visible: controller.assets.isEmpty, visible: controller.blendAssets.isEmpty,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
showSheetAlert(); showSheetAlert();
...@@ -173,7 +173,7 @@ import 'controller.dart'; ...@@ -173,7 +173,7 @@ import 'controller.dart';
) )
), ),
Visibility( Visibility(
visible: controller.assets.isNotEmpty, visible: controller.blendAssets.isNotEmpty,
child: makeShowAssetImageView(constraints.maxWidth - 20) child: makeShowAssetImageView(constraints.maxWidth - 20)
) )
], ],
......
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:pinput/pinput.dart'; import 'package:pinput/pinput.dart';
import '../../common/routers/names.dart'; import '../../common/routers/names.dart';
import '../../common/style/color.dart'; import '../../common/style/color.dart';
...@@ -22,6 +25,161 @@ Widget makeSectionTitleView(String index, String name) { ...@@ -22,6 +25,161 @@ Widget makeSectionTitleView(String index, String name) {
); );
} }
showSheetAlert() {
final controller = Get.find<AIDrawImageController>();
Get.bottomSheet(
SafeArea(
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20))
),
padding: const EdgeInsets.fromLTRB(20, 20, 20, 20),
height: 138,
child: Column(
children: [
InkWell(
onTap: () {
controller.selectTextImageUpload(ImageSource.camera);
Get.back();
},
child: Container(
height: 44,
width: Get.width - 40,
alignment: Alignment.center,
decoration: BoxDecoration(
color: AppColor.primary,
borderRadius: BorderRadius.circular(22)
),
child: Text("拍照"),
),
),
SizedBox(height: 10,),
InkWell(
onTap: () {
controller.selectTextImageUpload(ImageSource.gallery);
Get.back();
},
child: Container(
height: 44,
width: Get.width - 40,
alignment: Alignment.center,
decoration: BoxDecoration(
color: AppColor.primary,
borderRadius: BorderRadius.circular(22)
),
child: Text("相册"),
),
)
],
),
)
), persistent: false
);
}
Widget makeShowAssetImageView(double width) {
final controller = Get.find<AIDrawImageController>();
final count = controller.textAssets.length;
final children = List<Widget>.generate(count, (index) {
final element = controller.textAssets[index];
return Image.file(File(element.path), width: (width - 20) / 5.0, height: 160, fit: BoxFit.contain,);
});
return Container(
child: Stack(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
],
),
);
}
Widget makeInsertPictureView() {
final controller = Get.find<AIDrawImageController>();
// 插入图片
return Container(
height: 220,
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
decoration: BoxDecoration(
color: AppColor.gray3,
borderRadius: BorderRadius.circular(20)
),
child: LayoutBuilder(builder: (context, constraints) {
return Stack(
children: [
Obx(() => Visibility(
visible: controller.textAssets.isNotEmpty,
child: Positioned(
right: 0,
top: 0,
child: InkWell(
onTap: () {
controller.clearTextSelectedImage();
},
child: Image.asset("assets/images/清空图片.png", width: 30, height: 30,),
)
),
)
),
Column(
children: [
makeSectionTitleView("01.", "插入图片"),
SizedBox(height: 10,),
Container(
height: 160,
width: constraints.maxWidth - 20,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
decoration: BoxDecoration(
color: AppColor.black1,
borderRadius: BorderRadius.circular(10)
),
child: Obx(() => Stack(
children: [
Visibility(
visible: controller.textAssets.isEmpty,
child: InkWell(
onTap: () {
showSheetAlert();
},
child: Container(
height: 160,
width: constraints.maxWidth - 20,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image(image: AssetImage("assets/images/添加图片.png", ), width: 40, height: 40,),
SizedBox(height: 20,),
Text("支持图片格式:JPG/PNG,低于10M",
style: TextStyle(
fontSize: 12
),
),
]
),
),
)
),
Visibility(
visible: controller.textAssets.isNotEmpty,
child: makeShowAssetImageView(constraints.maxWidth - 20)
)
],
),
)
),
],
)
],
);
},)
);
}
Widget makeImageRandomItem(int index) { Widget makeImageRandomItem(int index) {
final controller = Get.find<AIDrawImageController>(); final controller = Get.find<AIDrawImageController>();
final item = controller.randomDescriptionItems[index]; final item = controller.randomDescriptionItems[index];
...@@ -135,7 +293,7 @@ Widget makeSectionTitleView(String index, String name) { ...@@ -135,7 +293,7 @@ Widget makeSectionTitleView(String index, String name) {
), ),
child: Column( child: Column(
children: [ children: [
makeSectionTitleView("01.", "输入描述词"), makeSectionTitleView("02.", "输入描述词"),
SizedBox(height: 10,), SizedBox(height: 10,),
Container( Container(
height: 160, height: 160,
...@@ -296,7 +454,7 @@ Widget makeSectionTitleView(String index, String name) { ...@@ -296,7 +454,7 @@ Widget makeSectionTitleView(String index, String name) {
), ),
child: Column( child: Column(
children: [ children: [
makeSectionTitleView("02.", "选择风格"), makeSectionTitleView("03.", "选择风格"),
SizedBox(height: 10,), SizedBox(height: 10,),
Divider( Divider(
color: AppColor.black1, color: AppColor.black1,
...@@ -381,7 +539,7 @@ Widget makeSectionTitleView(String index, String name) { ...@@ -381,7 +539,7 @@ Widget makeSectionTitleView(String index, String name) {
), ),
child: Column( child: Column(
children: [ children: [
makeSectionTitleView("03.", "选择画幅"), makeSectionTitleView("04.", "选择画幅"),
SizedBox(height: 10,), SizedBox(height: 10,),
Divider( Divider(
color: AppColor.black1, color: AppColor.black1,
...@@ -415,6 +573,7 @@ Widget makeSectionTitleView(String index, String name) { ...@@ -415,6 +573,7 @@ Widget makeSectionTitleView(String index, String name) {
return Stack( return Stack(
children: [ children: [
SingleChildScrollView( SingleChildScrollView(
controller: controller.textToImageController,
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
padding: EdgeInsets.fromLTRB(10, 10, 10, 70), padding: EdgeInsets.fromLTRB(10, 10, 10, 70),
child: Container( child: Container(
...@@ -440,6 +599,8 @@ Widget makeSectionTitleView(String index, String name) { ...@@ -440,6 +599,8 @@ Widget makeSectionTitleView(String index, String name) {
), ),
), ),
SizedBox(height: 20,), SizedBox(height: 20,),
makeInsertPictureView(),
SizedBox(height: 20,),
makeEnterDescriptiveWordsView(), makeEnterDescriptiveWordsView(),
SizedBox(height: 20,), SizedBox(height: 20,),
makeStyleSelectionView(), makeStyleSelectionView(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment