Text to Image Flutter Application Like DALE 2 | Flutter Text To Image Using Open Ai api

 



Here in this blog we will be looking at how we can build an entire application of Text to Image .We will use the open ai api for the generation of the images from the text . also if there is other available api for the text completion and code completion then we will be exploring it.

First thing to start you should head over to the open AI official website create an account if you haven't. If you have already created an account for it then head over to it by logging.and under the developer section get an apikey.This will be your one time api key . so copy that api key and store it somewhere you will not get the apikeys once it is lost.

Some of the Sample Photo is Below


In flutter Create the flutter projects . and the folder structure is like this 



.Here place the API key inside the API key folder. Generate Your Own because i will delete my apikey so the above API key wont work.

Also I have used shared preference and dark mode but this is optional . U can watch this video on YouTube for the minimalistic UI . I have skipped the shared preference and the login part in the YouTube video . If You Want the Straight Forward code then continue .


Here is list of code of all files inside of the lib folder.

The code for the main.dart file is as follow::

main.dart
import 'package:flutter/material.dart';
import 'package:o2openai/login/login.dart';
import 'Pages/HomePage.dart';
import 'package:o2openai/Themes/themes_const.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences sp = await SharedPreferences.getInstance();
bool darkmode = sp.getBool("darkmode") ?? false;
bool islogin = sp.getBool("islogin") ?? false;
String name = sp.getString("name") ?? "";
String imagepath = sp.getString("imagepath") ?? "";
runApp(MyApp(
darkmode: darkmode,
islogin: islogin,
name: name,
imagepath: imagepath,
));
}
// it think now this recording is far good then other
//now i think this is good recording than other
class MyApp extends StatefulWidget {
bool darkmode;
bool islogin;
String? name;
String? imagepath;
MyApp({
super.key,
required this.darkmode,
required this.islogin,
this.name,
this.imagepath,
});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: widget.darkmode ? customdarktheme : customlighttheme,
debugShowCheckedModeBanner: false,
home: Scaffold(
body: widget.islogin
? HomePage(
darkmode: widget.darkmode,
islogin: widget.islogin,
)
: LoginScreen(
darkmode: widget.darkmode,
)),
);
}
}


The code for the the themes_const under the themes file is as follow this is optional you can skip it .I have also skipped it in the YouTube Video.


themes_const.dart
import 'package:flutter/material.dart';
final ThemeData customlighttheme = ThemeData(
//custom theme for the container and text
brightness: Brightness.light,
scaffoldBackgroundColor: Colors.grey[300],
appBarTheme: const AppBarTheme(
backgroundColor: Color.fromARGB(255, 220, 220, 222),
foregroundColor: Colors.black),
//elevated button
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Color.fromARGB(255, 186, 17, 102)),
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
),
),
);
////
final ThemeData customdarktheme = ThemeData(
brightness: Brightness.dark,
scaffoldBackgroundColor: const Color.fromARGB(255, 52, 53, 65),
appBarTheme: const AppBarTheme(
backgroundColor: Color.fromARGB(255, 62, 63, 75),
foregroundColor: Colors.white),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Color.fromARGB(210, 186, 17, 101)),
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
),
),
);
// rgba(62,63,75,255)
// rgba(52,53,65,255)
// rgba(247,247,248,255)



// rgba(255,255,255,255)

The code for the login.dart under login folder  is as follow the name and password is 'admin' and 'admin' to successfully login. Shared preference packages is used for it to save login data locally. It was just me practicing Shared preference so i have used it but u may or may not used it also in the YouTube video above i have skipped that part.


login.dart
import 'package:flutter/material.dart';
import 'package:o2openai/main.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginScreen extends StatefulWidget {
bool? darkmode;
LoginScreen({super.key, this.darkmode});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
TextEditingController namecontroller = TextEditingController();
TextEditingController passwordcontroller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Login"),
),
body: Center(
child: Column(
children: [
textformfield(
hinttext: "Name",
controller: namecontroller,
textinputtype: TextInputType.emailAddress,
obscuretext: false,
prefixicon: Icons.email,
suffixicon: Icons.visibility,
suffixicononpressed: () {},
),
textformfield(
hinttext: "Password",
controller: passwordcontroller,
textinputtype: TextInputType.visiblePassword,
obscuretext: true,
prefixicon: Icons.lock,
suffixicon: Icons.visibility,
suffixicononpressed: () {},
),
//login button
ElevatedButton(
onPressed: () async {
if (namecontroller.text == "admin" &&
passwordcontroller.text == "admin") {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.setBool("islogin", true);
sp.setString("name", 'ADMIN');
//go to runapp
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
MyApp(darkmode: widget.darkmode!, islogin: true),
));
} else {}
},
child: const Text("Login"),
),
],
)),
);
}
}
Widget textformfield({
required String? hinttext,
required TextEditingController? controller,
required TextInputType? textinputtype,
required bool? obscuretext,
required IconData? prefixicon,
required IconData? suffixicon,
required Function? suffixicononpressed,
}) {
return TextFormField(
key: UniqueKey(),
validator: (value) {
if (value!.isEmpty) {
return "Please enter some text";
}
return null;
},
controller: controller,
keyboardType: textinputtype,
obscureText: obscuretext!,
decoration: InputDecoration(
hintText: hinttext,
prefixIcon: Icon(prefixicon),
suffixIcon: IconButton(
onPressed: suffixicononpressed as void Function()?,
icon: Icon(suffixicon),
),
),
);
}


 Also In the Pages all the screen are separately made .first HomePage which shows the HomeScreen and by navigating it we can go to three differrent screens first screen is for text to image conversion the second screen is for the text completion and the third screen is for the code completion which is incomplete . Also in the above YouTube Video there is only about the text to image generation part.In Future if i made for the text completion and the code completion then i will update the video above .


The code for the HomePages are as follow.

HomePage.dart
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../main.dart';
import 'o1ImageGenerationScreen.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'o2TextCompletionScreen.dart';
class HomePage extends StatefulWidget {
bool? darkmode;
bool? islogin;
HomePage({
super.key,
this.darkmode,
this.islogin,
});
@override
State<HomePage> createState() => _HomePageState();
}
// Qwermnbv@#123
class _HomePageState extends State<HomePage> {
IconData _iconlight = Icons.wb_sunny;
IconData _icondark = Icons.nights_stay;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
onPressed: () async {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.setBool("darkmode", !widget.darkmode!);
//rerun the entire app from myapp
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (BuildContext context) => MyApp(
darkmode: !widget.darkmode!,
islogin: widget.islogin!,
)));
},
icon: Icon(widget.darkmode! ? _icondark : _iconlight))
],
elevation: 0,
leading: IconButton(
onPressed: () {},
icon: const Icon(
FontAwesomeIcons.sun,
),
),
title: const Text("Open AI API BETA",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
)),
centerTitle: true,
),
body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
customButton(
tittletext: "Image Generations",
subtitletext: "Generate any images easily",
customicon: FontAwesomeIcons.solidImages,
colorone: const Color.fromARGB(135, 110, 5, 229),
colortwo: const Color.fromARGB(129, 56, 16, 188),
// textColor: Colors.black,
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
return const ImageGeneratingOpenApi();
// TextCompletion
},
));
},
context: context,
),
const SizedBox(height: 20),
customButton(
tittletext: "Text Completions",
subtitletext: "Generate and edit Text easily",
customicon: FontAwesomeIcons.penToSquare,
colorone: const Color.fromARGB(133, 14, 224, 182),
colortwo: const Color.fromARGB(129, 19, 187, 142),
// textColor: Colors.black, is this sufficient enough for the text
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
return const TextCompletion();
},
));
},
context: context,
),
const SizedBox(height: 20),
customButton(
//is this recording sufficetn
tittletext: "Code Completions",
subtitletext: "Generate edit and explain code ",
customicon: FontAwesomeIcons.code,
colorone: const Color.fromARGB(133, 218, 15, 221),
colortwo: const Color.fromARGB(129, 145, 16, 100),
// textColor: Theme.of(context).,
onPressed: () {
// print("code generation button pressed");
},
context: context,
),
SizedBox(height: 20),
//logout button
ElevatedButton(
onPressed: () async {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.setBool("islogin", false);
sp.remove('name');
//go to runapp
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
MyApp(darkmode: widget.darkmode!, islogin: false),
));
},
child: const Text("Logout"),
),
])),
);
}
}
Widget customButton(
{required String tittletext,
required String subtitletext,
required IconData customicon,
required Color colorone,
required Color colortwo,
// required Color textColor,
required onPressed,
context}) {
return GestureDetector(
onTap: onPressed,
child: Container(
// width: MediaQuery.of(context).size.width,
height: 80,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 65,
height: 80,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
colorone,
colortwo,
],
),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
bottomLeft: Radius.circular(10),
),
),
child: Icon(
customicon,
),
),
Container(
padding: EdgeInsets.only(left: 20),
width: 250,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
tittletext,
style: TextStyle(
// color: textColor,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
subtitletext,
style: TextStyle(
// color: textColor,
fontSize: 15,
),
),
],
)),
],
),
),
);






}




The Code for the Imagegeneration is as follow:

o1ImageGenerationScreen.dart
import 'package:flutter/material.dart';
import 'package:o2openai/apikey/apikey.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class ImageGeneratingOpenApi extends StatefulWidget {
const ImageGeneratingOpenApi({super.key});
@override
State<ImageGeneratingOpenApi> createState() => _ImageGeneratingOpenApiState();
}
class _ImageGeneratingOpenApiState extends State<ImageGeneratingOpenApi> {
var finalimages =
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTjB8TzJsR7ENk2PpjL9pem0W27QYdxT-qgCg&usqp=CAU';
final apikeys = api_keys;
TextEditingController TextToImage = TextEditingController();
Future<void> imagegenerate() async {
final url = Uri.parse("https://api.openai.com/v1/images/generations");
final headers = {
"Content-Type": "application/json",
"Authorization": "Bearer $apikeys"
};
var response = await http.post(url,
headers: headers,
body: jsonEncode({
"prompt": TextToImage.text,
"n": 3,
"size": "256x256",
}));
// print(response.statusCode);
if (response.statusCode == 200) {
var responseJson = jsonDecode(response.body);
finalimages = responseJson['data'][0]['url'];
} else {
// print("failed to generate image");
}
// print(finalimages);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(slivers: [
SliverAppBar(
toolbarHeight: MediaQuery.of(context).size.height * 0.07,
automaticallyImplyLeading: false,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(Icons.arrow_back),
color: Colors.black,
),
centerTitle: false,
actions: [
IconButton(
onPressed: () {},
icon: const Icon(
FontAwesomeIcons.sun,
color: Color.fromARGB(255, 62, 63, 75),
),
),
],
title: const Text("Image Generation Beta",
style: TextStyle(
color: Color.fromARGB(255, 62, 63, 75),
fontSize: 20,
fontWeight: FontWeight.bold,
)),
backgroundColor: Theme.of(context).appBarTheme.backgroundColor,
),
SliverList(
delegate: SliverChildListDelegate([
SizedBox(height: MediaQuery.of(context).size.height * 0.03),
Container(
height: MediaQuery.of(context).size.height * 0.1,
padding: const EdgeInsets.all(10),
child: TextField(
controller: TextToImage,
onSubmitted: (value) async {
setState(() {
finalimages = "";
});
},
decoration: InputDecoration(
hintText: "Search for an image",
hintStyle: const TextStyle(
color: Color.fromARGB(255, 62, 63, 75),
fontSize: 20,
// fontWeight: FontWeight.bold,
),
suffixIcon: IconButton(
onPressed: () {
//clear text in textfield
TextToImage.clear();
},
icon: const Icon(
Icons.clear,
color: Color.fromARGB(255, 62, 63, 75),
),
),
prefixIcon: const Icon(
Icons.search,
color: Color.fromARGB(255, 62, 63, 75),
),
filled: true,
fillColor: const Color.fromARGB(255, 240, 240, 240),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: Color.fromARGB(255, 240, 240, 240),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: BorderSide(
// color: Color.fromARGB(255, 240, 240, 240),
color: Colors.green.shade200),
),
),
),
),
Container(
padding: const EdgeInsets.all(10),
height: MediaQuery.of(context).size.height * 0.8,
child: FutureBuilder(
future: imagegenerate(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// print(finalimages.length);
return Column(
children: [
Container(
margin: const EdgeInsets.only(top: 5),
height: 256,
width: 256,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(finalimages.toString()),
fit: BoxFit.cover,
),
),
),
const SizedBox(height: 10),
//download button here
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(
height: 50,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor:
const Color.fromARGB(255, 245, 245, 246),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
child: const Text(
"Download",
style: TextStyle(
color: Colors.black,
fontSize: 17,
),
),
),
),
SizedBox(
height: 50,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor:
const Color.fromARGB(255, 245, 245, 246),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
child: const Text(
"Share",
style: TextStyle(
color: Colors.black,
fontSize: 17,
),
),
),
),
],
)
],
);
} else {
return Center(
child: CircularProgressIndicator(
color: Colors.grey[300],
),
);
}
},
),
)
]))
]),
);
}
}


The code for the Text Completion is as follow .Text completion is done by using the DaVinci 03 model which detail is available in open ai developer page so make sure to check it out.


o2TextCompletionScreen.dart
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:o2openai/apikey/apikey.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
class TextCompletion extends StatefulWidget {
const TextCompletion({super.key});
@override
State<TextCompletion> createState() => _TextCompletionState();
}
class _TextCompletionState extends State<TextCompletion> {
TextEditingController textsolution = TextEditingController();
// List<dynamic> textanswer = [];
String finaltextanswer = "";
Future<void> generateAnswer() async {
final url = Uri.parse(
"https://api.openai.com/v1/engines/davinci-codex/completions");
final headers = {
"Content-Type": "application/json",
"Authorization": "Bearer $api_keys"
};
final body = jsonEncode(
{"prompt": textsolution.text, "temperature": 0.5, "max_tokens": 100});
final response = await http.post(url, headers: headers, body: body);
if (response.statusCode == 200) {
final json = jsonDecode(response.body);
finaltextanswer = json['choices'][0]['text'];
print(finaltextanswer);
} else {
throw Exception("Failed to generate answer: ${response.statusCode}");
}
print(finaltextanswer);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
toolbarHeight: MediaQuery.of(context).size.height * 0.07,
automaticallyImplyLeading: false,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(Icons.arrow_back),
color: Colors.black,
),
centerTitle: false,
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.more_vert),
color: Colors.black,
),
],
title: const Text(
"Text Completion",
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
backgroundColor: Theme.of(context).appBarTheme.backgroundColor,
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Column(
children: [
//textformfield with validation
TextField(
controller: textsolution,
decoration: InputDecoration(
hintText: "Ask Anything",
hintStyle: const TextStyle(
color: Color.fromARGB(255, 62, 63, 75),
fontSize: 20,
// fontWeight: FontWeight.bold,
),
suffixIcon: IconButton(
onPressed: () {
textsolution.clear();
},
icon: const Icon(
Icons.clear,
color: Color.fromARGB(255, 62, 63, 75),
),
),
prefixIcon: const Icon(
Icons.search,
color: Color.fromARGB(255, 62, 63, 75),
),
filled: true,
fillColor: const Color.fromARGB(255, 240, 240, 240),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: Color.fromARGB(255, 240, 240, 240),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: BorderSide(
// color: Color.fromARGB(255, 240, 240, 240),
color: Colors.green.shade200),
),
),
onSubmitted: (value) async {
setState(() {});
},
),
SizedBox(height: 20),
//show the finaltextanswer calling the futurebuilder function
FutureBuilder(
future: generateAnswer(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Text(
finaltextanswer,
style: const TextStyle(
color: Color.fromARGB(255, 62, 63, 75),
fontSize: 20,
// fontWeight: FontWeight.bold,
),
);
} else {
return const Center(
child: CircularProgressIndicator(
color: Colors.white,
));
}
}),
],
)),
),
);
}




}


The Code Completion file isn't completed till now if completed then I will post it below. The main reason is there isn't good api for the code completion which is freely available . 


Also make to subscribe to the Chanell on YouTube For more flutter tips and tricks












Post a Comment

Previous Post Next Post