• Home
  • Flutter
    • All
    • App Templates
    • Designs
    • Resources
    • Widgets
    Quizlet Alternative AI: Study Notes to Flashcards

    Quizlet Alternative AI: Study Notes to Flashcards

    StickerAI

    StickerAI: AI Sticker Maker for iOS

    plants selling ui design

    Plants Selling Flutter UI App Design

    7 Best Flutter Repositories on GitHub

    7 Best Flutter Repositories on GitHub

    flutter ecommerce templates

    Top 8 Ecommerce Flutter App Templates

    best-flutter-ui-kits

    10 Best Flutter UI Kits

    AI image generator app - featured image.

    Create an AI Image Generator In Flutter, Clean Architecture Part 2

    Create an ai image generator in flutter

    Create an AI Image Generator In Flutter, Clean Architecture Part 1

    How To Create a Custom AppBar In Flutter

    How To Create a Custom AppBar In Flutter

  • My Apps
  • Recommendations
  • Backend
  • How-To-Guides
  • General
No Result
View All Result
Yassine Benkhay
  • Home
  • Flutter
    • All
    • App Templates
    • Designs
    • Resources
    • Widgets
    Quizlet Alternative AI: Study Notes to Flashcards

    Quizlet Alternative AI: Study Notes to Flashcards

    StickerAI

    StickerAI: AI Sticker Maker for iOS

    plants selling ui design

    Plants Selling Flutter UI App Design

    7 Best Flutter Repositories on GitHub

    7 Best Flutter Repositories on GitHub

    flutter ecommerce templates

    Top 8 Ecommerce Flutter App Templates

    best-flutter-ui-kits

    10 Best Flutter UI Kits

    AI image generator app - featured image.

    Create an AI Image Generator In Flutter, Clean Architecture Part 2

    Create an ai image generator in flutter

    Create an AI Image Generator In Flutter, Clean Architecture Part 1

    How To Create a Custom AppBar In Flutter

    How To Create a Custom AppBar In Flutter

  • My Apps
  • Recommendations
  • Backend
  • How-To-Guides
  • General
No Result
View All Result
Yassine Benkhay
No Result
View All Result

Create an AI Image Generator In Flutter, Clean Architecture Part 2

Yassine BENKHAY by Yassine BENKHAY
August 12, 2023
in Flutter
2
AI image generator app - featured image.
Share on FacebookShare on Twitter

Table of Contents

  • 1. Data Layer
  • 2. Repositories
  • 3. Presentation Layer: Controllers
  • 4. Conclusion of Part 2

In the first part of creating an AI Image Generator in Flutter With Clean Architecture, we talked about and understood the clean architecture in Flutter, the data flow, and the call flow and we finished the Domain Layer, In this part 2 of our series we’re going to continue from we left, and start working on the Data Layer.

Please ensure you complete the first part, as doing so will provide you with the foundation to follow along with what we will cover in this article.

Part 1: Create an AI Image Generator In Flutter With Clean Architecture

So with the context properly set, let’s proceed to the work ahead!

01
of 04
Data Layer

Models

In the models’ folder create an image_model.dart file with the ImageModel class extending the ImageEntity with a construction.

import '../../domain/entities/icon.dart';

class ImageModel extends ImageEntity{
  ImageModel(super.imageUrl);
}

Data Sources

In the data source folder create a remote_datasource.dart file with two classes:

the first is an abstract class, BaseRemoteDataSource with two methods getGeneratedImage and downloadImageFromUrl.

import '../../domain/entities/image.dart';
import 'dart:io';
abstract class BaseRemoteDataSource{
  Future<List<ImageEntity>> getGeneratedImage(String prompt);
  Future<File> downloadImageFromUrl(String url);
}

and the second class, RemoteDataSource which is implementing the one we’ve just created.

inside this class, we override the method and implement them, to generate images giving a prompt, and to download the image by its URL.

import '../model/image_model.dart';
import 'package:dart_openai/dart_openai.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
class RemoteDataSource implements BaseRemoteDataSource{
  @override
  Future<List<ImageEntity>> getGeneratedImage(String prompt) async{
    final generatedImages = await OpenAI.instance.image.create(
      prompt: prompt,
      n: 5,//number of images to generate.
    );
    List<ImageEntity> imagesData=generatedImages.data.map((eachImage) =>ImageModel(eachImage.url!) ).toList();
    return imagesData;
  }

  @override
  Future<File> downloadImageFromUrl(String url) async {

    var response = await Dio().get(
      url,
      options: Options(responseType: ResponseType.bytes),
    );
    final appDir = await getTemporaryDirectory();
    final file = File('${appDir.path}/image.jpg');
    await file.writeAsBytes(response.data);

    return file;
  }


}

the first method is getGeneratedImage returns a list of imageEntity and takes in a prompt.

inside this method, we create the generatedImages variable and call the create method from the OpenAI library passing in the prompt and the number of images we want to generate.

then we create a list of ImageEntity, called imagesData, and assign it the list of ImageEntity after we map through the generatedImages data and convert them to a list.

finally, we return the list.

for the second method which is responsible for downloading the image, we used the Dio package to get the image, then we use the path_provider package to get the temporary directory, then we create a file object appending the name “image.jpg”

and then write the response.data to the file object created earlier and finally we return it.

02
of 04
Repositories

Now let’s work in the concrete image repository, for that, in the repositories folder, create a concrete_image_repository.dart file that will have ConcreteImageRepository implementing the ImageRepository abstract class.

inside this class, we create a BaseRemoteDataSource instance injecting it into the ConcreteImageRepository constructor.

override the two methods, getImageByPrompt, and downloadImage.

inside the getImageByPrompt method, we call getGeneratedImage from the baseRemoteDataSource instance passing in the prompt.

and inside the downloadImage we call the downloadImageFromUrl from the baseRemoteDataSource instance passing in the URL.

import '../data_source/remote_datasource.dart';
import '../../domain/entities/image.dart';
import '../../domain/repository/image_repository.dart';
import 'dart:io';
class ConcreteImageRepository implements ImageRepository{
  final BaseRemoteDataSource baseRemoteDataSource;
  ConcreteImageRepository(this.baseRemoteDataSource);
  @override
  Future<List<ImageEntity>> getImageByPrompt(String prompt) async{
  return await baseRemoteDataSource.getGeneratedImage(prompt);
  }

  @override
  Future<File> downloadImage(String url) async{
    return await baseRemoteDataSource.downloadImageFromUrl(url);
  }

}

03
of 04
Presentation Layer: Controllers

we’ve done with the domain and data layer, now we’re going to work on the presentation layer, the UI.

Controllers

so inside the controller’s folder create another folder: get_image that will have two files, image_state.dart and image_cubit.dart.

Let’s first know what a cubit is.

Cubit is a lightweight state management solution. It is a subset of the bloc package.
Cubit does not rely on events and instead uses methods to emit new states.
Every cubit requires an initial state which will be the state of the cubit before emit has been called.

in the image_state.dart file create the different state the image can has:

import '../../../domain/entities/image.dart';

class ImageState{}
class ImageInitial extends ImageState{}

class ImageLoaded extends ImageState{
  final List<ImageEntity> loadedImages;
  ImageLoaded(this.loadedImages);
}
class ImageIsLoading extends ImageState{}
class ImageError extends ImageState{
  final String errorMessage;
  ImageError(this.errorMessage);
}

for the imageLoaded state class we create a list of the loaded images and pass them through the constructor so when we emit the state we emit it with the loaded images.

same thing if an error occurred, we pass through to the ImageError constructor the error message.

Now, let’s work on the image_cubit.dart file, for that go ahead and create an ImageCubit class that extend Cubit of type ImageState state: Cubit<ImageState>.

then we create ImageRepository instance and pass it to the ImageCubit constructor, as we said, every cubit need an initial state so we call the super (ImageInitial( )).

inside this class we class the getImage method that will emit the image states as follows:

import '../../../domain/entities/image.dart';
import '../../../domain/usecases/get_image_by_prompt.dart';
import 'package:dart_openai/dart_openai.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../domain/repository/image_repository.dart';
import 'image_state.dart';

class ImageCubit extends Cubit<ImageState>{
  final ImageRepository imageRepository;
  ImageCubit(this.imageRepository):super (ImageInitial());
  Future<void> getImage(String prompt)async{
    emit(ImageInitial());
  try{
    emit(ImageIsLoading());
    List<ImageEntity> gottenImage= await GetImageByPrompt(imageRepository).getTheImageByPrompt(prompt);
 emit(ImageLoaded(gottenImage));

  }catch (e) {
    if (e is RequestFailedException) {
      emit(ImageError(e.message));
    } else {
      emit(ImageError("Unknown error occurred."));
    }
  }}
}

we emit the ImageInnial first, in the try block, we emit the ImageIsLoading then we call the getTheImageByPrompt from GetItmageByPrompt use case passing the imageRepository instance.

and then we emit the ImageLoaded state.

and if an error happened we emit the error message.

Let’s work now on the downloading the images, for that, inside the controllers folder create another folder, download_image and create two files.

download_image_state.dart and download_image_cubit.dart.

for the download image state create the necessary states as follows:

import 'dart:io';
class DownloadImageState{}

class DownloadImageInitial extends DownloadImageState{}
class DownloadImageDone extends DownloadImageState{}
class Downloading extends DownloadImageState {}
class DownloadError extends DownloadImageState{
  final String errorMessage;
  DownloadError(this.errorMessage);
}
import 'download_image_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../domain/repository/image_repository.dart';
import '../../../domain/usecases/download_image.dart';
import 'dart:io';
class DownloadImageCubit extends Cubit<DownloadImageState> {
  final ImageRepository imageRepository;

  DownloadImageCubit(this.imageRepository) : super(DownloadImageInitial());

  Future<File> downloadImage(String url) async {
    emit(DownloadImageInitial());
    try {
    emit(Downloading());
      File downloadedImage =
      await DownloadImage(imageRepository).downloadImageByItsUrl(url);
      emit(DownloadImageDone());
      return downloadedImage;
    } catch (e) {

      emit(DownloadError("Unable to download the image"));

    }
    throw("cant download image");
  }


}

In the downloadImageCubit we have the downloadImage method where we emit the different states.

we call downloadImageByItsUrl method form the DownloadImage use cases that that take the imageRepository instance.

and we catch errors if any.

04
of 04
Conclusion of Part 2

By now our data is ready and we can generate images and download them, we finished the data layer and finished the controllers from the presentation layer.

In the next article we will work on the UI part where we will leverage the controllers so we can call its methods to generate and download images.

If you found this article helpful or have any thoughts, questions, or additional insights, I’d love to hear from you! Your feedback is incredibly important in helping me improve the quality of my content.

Found an error or want to add to the discussion? Please don’t hesitate to leave a comment below or reach out to me on LinkedIn.

Previous Post

Create an AI Image Generator In Flutter, Clean Architecture Part 1

Next Post

Create an AI Image Generator, Flutter Clean Architecture Part 3

Yassine BENKHAY

Yassine BENKHAY

Hey there, my name is Yassine. I am a bachelor degree in computer systems and software engineering, and a mobile flutter developer, refer to about me page for more information.

Related Posts

Quizlet Alternative AI: Study Notes to Flashcards
Recommendations

Quizlet Alternative AI: Study Notes to Flashcards

by Yassine BENKHAY
November 15, 2024
0

Introduction In today’s fast-paced academic environment, students need tools that adapt to their learning styles. While Quizlet has long been...

Read more
StickerAI

StickerAI: AI Sticker Maker for iOS

October 9, 2024
plants selling ui design

Plants Selling Flutter UI App Design

November 28, 2023
7 Best Flutter Repositories on GitHub

7 Best Flutter Repositories on GitHub

November 10, 2023
flutter ecommerce templates

Top 8 Ecommerce Flutter App Templates

October 18, 2023
best-flutter-ui-kits

10 Best Flutter UI Kits

October 17, 2023
Next Post
Create an AI Image Generator, Flutter Clean Architecture Part 3

Create an AI Image Generator, Flutter Clean Architecture Part 3

Comments 2

  1. Pingback: Create an AI Image Generator, Flutter Clean Architecture Part 3
  2. Pingback: Create an AI Image Generator In Flutter With Clean Architecture

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Subscribe to Our Newsletter

Flutter Premium Templates

How-To-Guides

Cake with pecans and caramel from the southern region

May 11, 2025
Cake with pecans and caramel from the southern region

📝 Ingredients For the Cake: 2½ cups all-purpose flour 2 cups granulated sugar 1 cup unsalted butter, at room temperature...

Read more
by Yassine BENKHAY
0 Comments
Recommendations

Quizlet Alternative AI: Study Notes to Flashcards

November 15, 2024
Quizlet Alternative AI: Study Notes to Flashcards

Introduction In today’s fast-paced academic environment, students need tools that adapt to their learning styles. While Quizlet has long been...

Read more
by Yassine BENKHAY
0 Comments
Recommendations

StickerAI: AI Sticker Maker for iOS

October 9, 2024
StickerAI

Looking for a fun and simple way to create personalized stickers for your chats, social media, or even printed products?...

Read more
by Yassine BENKHAY
0 Comments
Yassine Benkhay

Terms & conditions | Privacy Policy | About me | Contact
© 2024 yassinebenkhay.com All rights reserved.

Quick Links

  • Home
  • Flutter
  • My Apps
  • Recommendations
  • Backend
  • How-To-Guides
  • General

Let's keep in touch!

No Result
View All Result
  • Home
  • Flutter
  • My Apps
  • Recommendations
  • Backend
  • How-To-Guides
  • General

Terms & conditions | Privacy Policy | About me | Contact
© 2024 yassinebenkhay.com All rights reserved.