membuat text to image app dengan openai

Membuat Text to Image App dengan OpenAI

Pada tutorial kali ini Anda akan belajar membuat text to image app dengan menggunakan model dari OpenAI. Secara garis besarnya web aplikasi yang Anda buat akan mengubah text yang diinputkan menjadi sebuah gambar.

Disini kita akan menggunakan Node js sebagai backend atau server nya. Sedangkan untuk frontend atau clientnya menggunakan react js.

Sebelum mengikuti tutorial ini, Anda harus memiliki  Node >= 14.0.0 and npm >= 5.6 pada komputer Anda.

Membuat Server Open AI API

Pertama Anda buat folder terlebih dahulu dengan nama text-to-image-openai. Buka folder tersebut dan buat 2 folder yaitu server dan client.

Jika Anda sudah membuat ke 2 folder diatas, maka selanjutnya buka terminal di folder root dan jalankan perintah berikut.

cd server
npm init -y

Buka folder server dan Anda akan melihat file package.json

Disini Anda perlu menginstall beberapa module seperti express, dotenv, cors, dan openai. Gunakan perintah berikut untuk menginstall semua module yang akan digunakan.

npm install express dotenv cors openai

Setelah proses instalasi module selesai, kemudian Anda perlu membuat file index.js

Pada file tersebut Anda akan mengimport module yang barusan diinstall.

import express from "express";
import * as dotenv from "dotenv";
import cors from "cors";
import { Configuration, OpenAIApi } from "openai";

Selanjutnya, kita akan membuat configurasi untuk openai dan juga express seperti code berikut.

dotenv.config();

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});

const openai = new OpenAIApi(configuration);

const app = express();
app.use(cors());
app.use(express.json());

Kode diatas dimulai dengan memuat variabel lingkungan dari file “.env” menggunakan pustaka dotenv. Kemudian membuat objek Konfigurasi yang menyimpan kunci API OpenAI dari variabel lingkungan. Selanjutnya, kode membuat instance dari kelas OpenAIApi dengan objek konfigurasi. Ini diikuti dengan mengonfigurasi middleware seperti CORS dan JSON parser pada aplikasi ekspres. Terakhir, kode menjalankan server web pada port 5000 (atau port lain yang ditentukan oleh environtment variabel PORT) dan mencetak pesan log yang mengindikasikan bahwa server sedang berjalan.

Pada bagian configurasi OpenAIApi Anda perlu memasukkan apiKey. Jika Anda belum memiliki apiKey, Anda bisa membuatnya di https://openai.com/api/

Lakukan registrasi pada website openai jika Anda tidak memiliki akun. Jika Anda sudah memiliki akun, Anda bisa langsung login. Nantinya Anda akan diarahkan ke halaman berikut. Setelah itu, Anda klik tulisan Personal dan akan muncul menu drop-down. Lalu klik View API keys.

open ai api

Setelah itu, klik tombol Create new secret key dan jangan lupa copy API keys yang Anda dapatkan. Anda perlu membuat file .env dan pastekan API Keys Anda ke file tersebut seperti ini.

OPENAI_API_KEY="your-openai-api-key"
PORT=5000

Lalu buka kembali file index.js dan kita akan buat request get untuk melihat jika server yang dibuat berjalan.

app.get("/", async (req, res) => {
  res.status(200).send({
    message: "Hello from Open AI Generate Image",
  });
});

Kode diatas akan mendefinisikan permintaan HTTP app.get. Permintaan ini membutuhkan dua parameter: sebuah string yang dimasukkan ke dalam parameter pertama (/) yang menunjukkan URL akar server dan fungsi callback yang mengambil dua parameter (req, res). Ketika klien mengirimkan permintaan GET ke rute ini, fungsi callback akan mengeksekusi dan merespons dengan kode status 200 dan objek JSON yang berisi pesan “Hello from Open AI Generate Image”.

Sekarang saatnya Anda membuat request untuk mengubah text to image. Disini kita akan menerima request body dari user dengan nama prompt. Kemudian kita panggil fungsi createImage() untuk membuat image. Pada fungsi tersebut kita masukan 3 parameter yaitu prompt, n, size.

  • prompt: input text yang akan diubah menjadi image
  • n: jumlah gambar yang akan digenerate
  • size: ukuran gambar
app.post("/", async (req, res) => {
  try {
    const prompt = req.body.prompt;

    const response = await openai.createImage({
      prompt: `${prompt}`,
      n: 1,
      size: "1024x1024",
    });

    res.status(200).send({
      image_url: response.data.data[0].url,
    });
  } catch (error) {
    console.error(error);
    res.status(500).send(error || "Something went wrong");
  }
});

Terakhir, kita panggil fungsi listen untuk menjalankan server pada PORT 5000.

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`);
});

Sekarang Anda bisa menjalankan server dengan menggunakan perintah berikut.

node index.js

Jika berhasil maka akan muncul pesan “Hello from Open AI Generate Image”.

Untuk server-side sudah selesai, kemudian kita akan lanjut ke client-side dengan menggunakan react js.

Membuat Client

Pertama Anda kembali ke folder project dan masuk ke dalam folder client. Pada folder client Anda perlu membuat environment untuk react dengan perintah berikut.

npx create-react-app .

Setelah itu, Anda perlu menginstall axios untuk menghandle request post ke server.

npm install axios

Hapus semua code pada file src/App.js dan kita ganti yang pertama yaitu dengan mengimport module yang akan digunakan.

import React, { useState } from "react";
import axios from "axios";
import "./App.css";

Selanjutnya, Anda perlu membuat function App() seperti berikut.

function App() {
  
}

export default App;

Kemudian Anda perlu menambahkan state yaitu:

  • data: untuk menerima result data dari server atau hasil generate image
  • prompt: untuk menerima input text dari user
  • isLoading: untuk mengecek loading saat request post ke server
  • error: untuk menerima pesan error jika terjadi kesalahan saat generate image
const [data, setData] = useState([]);
const [prompt, setPrompt] = useState("");
const [isLoading, setLoading] = useState(false);
const [error, setError] = useState("");

Sekarang Anda perlu membuat fungsi async untuk melakukan generate image.

const generateImage = async (event) => {
    event.preventDefault();
    setLoading(true);
    setError("");

    await axios
      .post("http://localhost:5000", {
        prompt,
      })
      .then((response) => setData(response.data.image_url))
      .catch((error) => setError(error.message));

    setLoading(false);
};

Kode diatas menggunakan fungsi yang disebut generateImage() untuk melakukan pemanggilan axios ke backend. Kode ini mengambil sebuah event sebagai parameter dan mencegah tindakan default. Untuk melakukan hal ini, preventDefault() dipanggil pada objek event.

Fungsi ini kemudian mengatur status loader menjadi true dan error menjadi string kosong.

Await axios dilakukan ke http://localhost:5000 dengan mengirimkan prompt yang disimpan dalam variabel prompt state. Jika respons berhasil, response.data.image_url akan disetel ke data variabel state. Jika terjadi kegagalan, pesan kesalahan diatur ke variabel error. Terakhir, status loading diatur ke false.

Kemudian, Anda perlu membuat component seperti berikut.

return (
    <div className="App">
      <input className="c-checkbox" type="checkbox" id="checkbox" />
      <div className="c-formContainer">
        <form
          className={"c-form " + (data ? "result-img" : "")}
          onSubmit={generateImage}
        >
          <input
            className="c-form__input"
            type="text"
            placeholder="Text to image"
            value={prompt}
            onChange={(e) => setPrompt(e.target.value)}
          />
          <label className="c-form__buttonLabel" htmlFor="checkbox">
            <button className="c-form__button" type="submit">
              Generate
            </button>
          </label>
          <label
            className="c-form__toggle"
            htmlFor="checkbox"
            data-title="Generate Image"
          ></label>
        </form>
      </div>
      {isLoading ? (
        <div className="loader"></div>
      ) : (
        <div className="c-formContainer">
          {error ? <h2>{error}</h2> : <img src={data} width="90%" />}
        </div>
      )}
    </div>
  );

Untuk lebih mempercantik lagi ubah file src/App.css menjadi seperti berikut.

body {
  font-size: 10px;
  font-family: Roboto, sans-serif;
  background-color: #ff7b73;
  margin: 0;
  display: grid;
  height: 100vh;
  place-items: center;
}

img {
  margin-top: 50px;
}

.c-checkbox {
  display: none;
}

.c-checkbox:checked + .c-formContainer .c-form {
  width: 37.5em;
}

.c-checkbox:checked + .c-formContainer .c-form__toggle {
  visibility: hidden;
  opacity: 0;
  transform: scale(0.7);
}

.c-checkbox:checked + .c-formContainer .c-form__input,
.c-checkbox:checked + .c-formContainer .c-form__buttonLabel {
  transition: 0.2s 0.1s;
  visibility: visible;
  opacity: 1;
  transform: scale(1);
}

.c-formContainer,
.c-form,
.c-form__toggle {
  width: 20em;
  height: 6.25em;
}

.c-formContainer {
  position: relative;
  font-weight: 700;
}

.c-form,
.c-form__toggle {
  position: absolute;
  border-radius: 6.25em;
  background-color: #ffffff;
  transition: 0.2s;
}

.c-form {
  left: 50%;
  transform: translateX(-50%);
  padding: 0.625em;
  box-sizing: border-box;
  box-shadow: 0 0.125em 0.3125em rgba(0, 0, 0, 0.3);
  display: flex;
  justify-content: center;
}

.c-form__toggle {
  color: #ff7b73;
  top: 0;
  cursor: pointer;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.c-form__toggle::before {
  font-size: 1.75em;
  content: attr(data-title);
}

.c-form__input,
.c-form__button {
  font: inherit;
  border: 0;
  outline: 0;
  border-radius: 5em;
  box-sizing: border-box;
}

.c-form__input,
.c-form__buttonLabel {
  font-size: 1.75em;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.7);
  transition: 0s;
}

.c-form__input {
  color: #000000;
  height: 100%;
  width: 100%;
  padding: 0 0.714em;
}

.c-form__buttonLabel {
  color: #ffffff;
  height: 100%;
  width: auto;
}
.c-form__buttonLabel::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  pointer-events: none;
  cursor: pointer;
}

.c-form__button {
  color: inherit;
  padding: 0;
  height: 100%;
  width: 5em;
  background-color: #000000;
  cursor: pointer;
  transition-duration: 0.4s;
}

.c-form__button:hover {
  background-color: #ff7b73;
  color: #000000;
}

.loader {
  border: 16px solid #f3f3f3;
  border-radius: 50%;
  border-top: 16px solid #3498db;
  width: 50px;
  height: 50px;
  -webkit-animation: spin 2s linear infinite; /* Safari */
  animation: spin 2s linear infinite;
  margin-top: 50px;
  margin-left: 50px;
}

/* Safari */
@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

Pada bagian terakhir kita ubah sedikit untuk file src/index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Sekarang Anda jalankan client dengan perintah berikut.

npm start

Jangan lupa untuk menjalankan server-nya juga. Anda bisa buka client pada http://localhost:3000

Nantinya tampilan website akan seperti ini.

text to image client

Untuk full code nya, Anda bisa lihat di link berikut ini.

Leave a Comment

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

Scroll to Top