DEV Community

Cover image for # BUILDING AN IMAGE GENERATOR USING FLET WITH PYTHON
Arsey Kun
Arsey Kun

Posted on

# BUILDING AN IMAGE GENERATOR USING FLET WITH PYTHON

Introduction

Hello there software developers 👨‍💻, Arsey here👋,

Sorry for the late update, i'm a student and was working on some personal projects, but i'll be keeping up and keeping you update from now on.

So in my last tutorial someone commented if we can use GenAI in python frameworks such as kivy and flet, my answer was yes, you can build GenAI apps with them. It might not be the most scalable ones but for a side project with these frameworks are quiet a go to.

In this tutorial, we will be building a simple Image Generator App in python with flet and an image generation model known as flux.dev.

Since flux is a powerful image generator model it requires high computing power to run on your machine, my machine is that powerful so here we will be using replicate, a platform that will provide us an API endpoint for flux such that we focus on user experience, and the image generation will be handled by the API, so no system crush downs or lags, though you can use huggingsface which also has the flux API but follow along we will go with replicate. what are we waiting for, let’s dive in.

Prerequisites

Before we start building our application, I recommend that you have a basic knowledge with python basics such as functions and some oop concepts, and make sure you have the necessary packages installed in your system, we will using the following packages:

  • flet for building the user interface, for those who don't know Flet. Flet is a python library based on flutter one of the most loved mobile frameworks. Flet allows us to build quick and beautiful user interfaces in real-time and can run cross-platform.

  • replicate Replicate is a platform as a service (PAAS), a platform that will provide us pre-made models that we can use without installing them. What I mean here is that, replicate will provide the API endpoints that we will hit from our application. Replicate will handle the requests and response in the cloud as for you focus on the functionalities of your application without worrying.

  • requests for our API endpoint here we will be able to send request and receive responses from and to replicate.

  • Oh even os for file management, this will be allowing us to save our image on our local system.

Project setup (environment setup)

Install required packages,

pip install flet replicate request

Once installed, and ready to mess with your keyboard; you need to create an account with replicate from here create replicate account make sure to authenticate and authorize using your GitHub credentials.

After creating your account, you’ll now be redirected to the replicate dashboard, here you’ll be able to see different models, but for this tutorial we’ll be using flux.dev. find and use the flux.dev model, any other modek chosen could also work.

Reminder install replicate to able to use their API. All done, then head over to replicate and create an API token, this will set up an endpoint from replicate to our client side app.

Note: the dev version is not used in production or commercial purposes, and be aware that you have limited tokens to use the free version of the model, so do not get excited and generate random images or else you’ll lose all your free credits.

Now where were we, oh well i think you have everything setup to this point, let's go play with the their API.

Building the user interface

Firstly we will be building the User Interface, by the end of this part you'll have a mock UI, ready now, open up your favorite IDE/code editor and type in this code.

import os
import flet as ft
import replicate
import requests

# Set the Replicate API token in the environment
os.environ["REPLICATE_API_TOKEN"] = "YOUR_API_TOKEN"

# Function to interact with Replicate API for image generation
def generate_image(prompt):
    pass

# Function to save the image locally
def save_image(image_url, filename="generated_image.webp"):
    pass

# Main function to define the Flet app
def main(page: ft.Page):
    page.title = "ArseyGen"
    page.horizontal_alignment = 'center'
    page.scroll = ft.ScrollMode.AUTO
    page.theme_mode = ft.ThemeMode.DARK

    page.appbar = ft.AppBar(
        title=ft.Text("REPLICATE IMAGE GENERATOR"), center_title=True
    )

    # Placeholder image to avoid missing src error
    result_image = ft.Image(
        src="https://via.placeholder.com/512", width=512, height=512
        )

    # Define the save button (initially disabled)
    save_image_button = ft.ElevatedButton(text="Save Image", disabled=True)

    # Function to handle image generation
    def generate_and_display_image(e):
        pass

    prompt_input = ft.TextField(label="Enter a text prompt")
    generate_button = ft.ElevatedButton(
        text="Generate Image", on_click=generate_and_display_image
        )

    # Add components to the page
    page.add(
        ft.SafeArea(
            content=ft.Column(
                [
                    prompt_input,
                    generate_button, result_image,
                    save_image_button,
                ],
                horizontal_alignment=ft.CrossAxisAlignment.CENTER
            )
        )
    )

# Run the Flet app
if __name__ == '__main__':
    ft.app(target=main)
Enter fullscreen mode Exit fullscreen mode

Output
you'll have soemthing like this for this step,
simple user interface

Code Explanation

Here is what we have done, we first import our required modules.
we then set our api_token provded by replicate.
then here we set our placeholder functions which will be used later, we used a pass statement
to ignore them.

The main function then describes and builds our UI, here we set the page title, alignment,
scroll behavour so that our page is scrollable. and the rest are UI elements, as You can see we have the AppBar, Image which will allow us to display images in our UI, and finally we
add TextField to capture user's prompts; Generate and Save buttons to handle image generation and saving respectively.

Finally we add our components to the page, notice we used the SafeArea, this will help us provde suffcient padding and avoid intrusions by the operating system, In our case it will indent
the Column widget to avoid the AppBar from interpolating, as for the Column widget, allows us to display UI elements in a vertical array.

Integrating replicate

I can feel your excitement, this is the most crutial step, so make sure you make no mistakes or you'll end breaking the code, and end up debugging, oh well debugging is a good skill cause it took me 2days to fix the ui and 3days to debug the api endpoint where I had an invalid token.

Frustrating right, so if you encounter any bugs/errors in the process try to debug and see the results, I'll do my best able to assist you, so ask questions may be I or other devs will help.

Okay now let's integrate the model, head over to replicate and such for flux.dev.
copy the code provided and we'll make some changes to it, okay! done.

Update the generate_image function so it looks something like this,

 def generate_image(prompt):
    try:
        # Make the API call to Replicate to generate an image
        output = replicate.run(
            "bingbangboom-lab/flux-dreamscape:b761fa16918356ee07f31fad9b0d41d8919b9ff08f999e2d298a5a35b672f47e",
            # "black-forest-labs/flux-dev",
            input={
                "model": "dev",
                "prompt": prompt,
                "lora_scale": 1,
                "num_outputs": 1,
                "aspect_ratio": "1:1",
                "output_format": "webp",
                "guidance_scale": 3.5,
                "output_quality": 80,
                "prompt_strength": 0.8,
                "extra_lora_scale": 0.8,
                "num_inference_steps": 28
            }
        )
        # Return the generated image URL
        return output[0]
    except Exception as e:
        print(f"Error: {e}")
        return None
Enter fullscreen mode Exit fullscreen mode

what this function does is, it interacts with the Replicate API to generate an image base on the text prompt provided by the user.
it then sends the prompt and other model parameters
to the API and returns the URL of the generated image, and if soemthing goes wrong, it handles the error by returning None.

Paste your API token copied from replicate. so it looks something like this,

os.environ["REPLICATE_API_TOKEN"]="r8_KhysOWTKUjRsagyyyLNIWvvg2K78qrE48RwTh"

Ensure you have the token, you can get your API Token from get your api token here

Applying the generate and display image function

Once done, let's also update the generate_and_display_image function, type in this code below,

def generate_and_display_image(e):
        prompt = prompt_input.value
        if prompt:
            page.splash = ft.ProgressBar()  # Display progress bar while generating image
            page.update()

            # Generate image based on user's prompt
            image_url = generate_image(prompt)
            page.splash = None  # Hide progress bar

            if image_url:
                # Update image source only if we have a valid URL
                result_image.src = image_url
                result_image.update()

                # Enable save button after image is generated
                save_image_button.disabled = False
                save_image_button.update()

                # Define save button's functionality (save the image locally when clicked)
                def save_image_click(e):
                    save_image(image_url, "anime.webp")

                save_image_button.on_click = save_image_click

            else:
                # Display an error message if image generation fails
                page.dialog = ft.AlertDialog(
                    title=ft.Text("Error"),
                    content=ft.Text("Failed to generate image. Please try again."),
                    actions=[
                        ft.TextButton(
                            "OK",
                            on_click=lambda _: page.dialog.close()
                            )
                        ]
                    )

                page.dialog.open = True
                page.update()
Enter fullscreen mode Exit fullscreen mode

At this point, when you run the application, try entering a prompt and click the generate button, you'll see a progress bar and within seconds you'll see the image generated in your UI. And remember don't over generate or you'll lose your credits. and i promise you it won't be fun.

Code Explanation

This function here manages the workflow of generating and displaying the imge in the our application. it takes the user's prompt, calls the generate_image() to
generate the image_url and updates the App UI with the result_image. if the process fails, it shows an error dialog. and also t Enables the "Save Image" button after the image is successfully generated.

Applying the save_image function

Getting tired already save your energy, take some coffee and complete the project cause we are now gonna add the saving function.

So far we have the basic User interface and we can now generate images successfully, but we have a problem, what if we want to save our images on our system, cause now our current application just generates and...
its done, to solve this we have to add the save function.

So in your code update the save_image function to look something like this:

def save_image(image_url, filename="generated_image.webp"):
    try:
        response = requests.get(image_url)
        if response.status_code == 200:
            with open(filename, 'wb') as f:
                f.write(response.content)
            print(f"Image saved successfully as {filename}")
        else:
            print(f"Failed to download image. Status code: {response.status_code}")
    except Exception as e:
        print(f"Error saving image: {e}")
Enter fullscreen mode Exit fullscreen mode

Code explanation

Now what have done here, let's break it down.
This function allows us to download and save the generate_image to the local system. it takes the image_url and an optional filename, retrieves the image data via an HTTP request, and writes it to file.
it ensures error handling in case the download fails.

Conclusion

Well! that's it fellow deveolopers, a simple image generator using python, flet and flux.
It has been fun working on this project and would like to here from you.

Here is my final output,

elon musk's red teslor

I haven't been uploading since i was in a recent hackathon and I'm also writing a book for students, as well as working professions and it has been a headache embrace thus paused some programming and rest for a while.

But now I'll be uploading content from now.

Thanks for being patient, I'll upload more for you devs.

Top comments (0)