首頁 >web前端 >js教程 >使用 ReactJS 建立免費的 AI 圖像生成器

使用 ReactJS 建立免費的 AI 圖像生成器

Patricia Arquette
Patricia Arquette原創
2024-10-15 12:23:30888瀏覽

開發者們大家好,
今天,我將向您展示如何使用 ReactJS 創建圖像生成器,並且完全可以免費使用,這要感謝黑森林實驗室和 Together AI。

第 1 步:設定項目

在本教程中,我們將使用 Vite 來初始化應用程式並使用 Shadcn 來初始化 UI。我假設您已經設定了專案並安裝了 Shadcn。

第 2 步:安裝 Together AI 軟體包

我們需要安裝 Together AI 套件才能存取免費的 Flux 模型來產生映像。
在終端機中執行以下命令

npm i together-ai

第 3 步:建立使用者介面

現在,讓我們為我們的應用程式建立 UI。以下是圖像生成器組件的完整程式碼。它包括提示文字輸入。用於選擇寬高比的下拉式選單。
請記住,我們需要使用“black-forest-labs/FLUX.1-schnell-Free”,因為它是免費的。

import { useRef, useState } from "react";
import Together from "together-ai";
import { ImagesResponse } from "together-ai";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { motion } from "framer-motion";
import { Separator } from "@/components/ui/separator";
import { DownloadIcon } from "@radix-ui/react-icons";
import { save } from "@tauri-apps/plugin-dialog";
import { writeFile } from "@tauri-apps/plugin-fs";

function App() {
  const [input, setInput] = useState("");
  const [imageUrl, setImageUrl] = useState("");
  const [ratio, setRatio] = useState("9:16");
  const [isLoading, setIsLoading] = useState(false);
  const [downloading, setDownloading] = useState(false);
  const imageRef = useRef<htmlimageelement>(null);

  const hRatio = ratio.split(":").map(Number)[0];
  const vRatio = ratio.split(":").map(Number)[1];

  const width = hRatio === 1 ? 512 : hRatio * 64;
  const height = vRatio === 1 ? 512 : vRatio * 64;

  const together = new Together({
    apiKey: import.meta.env.VITE_TOGETHER_API_KEY,
  });

  const handleGenerateImage = async () => {
    setIsLoading(true);

    try {
      console.log(width, height);
      const response: ImagesResponse = await together.images.create({
        model: "black-forest-labs/FLUX.1-schnell-Free",
        prompt: input,
        width: width,
        height: height,
        // @ts-expect-error response_format is not defined in the type
        response_format: "b64_json",
      });

      const base64Image = response.data[0].b64_json;
      const dataUrl = `data:image/png;base64,${base64Image}`;
      setImageUrl(dataUrl);
    } catch (error) {
      console.error("Error generating image:", error);
      // You might want to add some error handling UI here
    } finally {
      setIsLoading(false);
    }
  };

  const handleDownloadImage = async () => {
    if (imageUrl) {
      setDownloading(true);
      try {
        // Remove the data URL prefix
        const base64Data = imageUrl.replace(/^data:image\/\w+;base64,/, "");

        // Convert base64 to binary
        const imageBuffer = Uint8Array.from(atob(base64Data), (c) =>
          c.charCodeAt(0)
        );

        // Open a save dialog
        const filePath = await save({
          filters: [
            {
              name: "Image",
              extensions: ["png"],
            },
          ],
        });

        if (filePath) {
          // Write the file
          await writeFile(filePath, imageBuffer);
          console.log("File saved successfully");
        }
      } catch (error) {
        console.error("Error saving image:", error);
      } finally {
        setDownloading(false);
      }
    }
  };

  return (
    <div classname="bg-gradient-to-br from-indigo-100 via-purple-100 to-pink-100 p-10 md:p-8">
      <motion.div initial="{{" opacity: y: animate="{{" transition="{{" duration: classname="max-w-7xl mx-auto bg-white/80 backdrop-blur-sm rounded-3xl shadow-2xl overflow-y-auto">
        <div classname="flex flex-col md:flex-row h-[calc(100vh-4rem)]">
          <div classname="w-full md:w-1/2 p-6 flex flex-col">
            <h2 classname="text-3xl font-bold mb-6 text-gray-800 bg-clip-text text-transparent bg-gradient-to-r from-indigo-500 to-purple-600">
              AI Image Generator for "Thảo"
            </h2>
            <div classname="flex-grow flex flex-col justify-center">
              <textarea value="{input}" onchange="{(e)"> setInput(e.target.value)}
                placeholder="Describe the image you want to create..."
                className="mb-4 resize-none rounded-2xl border-2 border-indigo-200 focus:border-indigo-500 transition-colors"
                rows={5}
              />
              <div classname="flex items-center space-x-4 mb-6">
                <select value="{ratio}" onvaluechange="{setRatio}">
                  <selecttrigger classname="w-full rounded-full border-2 border-purple-200 focus:border-purple-500 transition-colors">
                    <selectvalue placeholder="Select ratio"></selectvalue>
                  </selecttrigger>
                  <selectcontent>
                    <selectitem value="1:1">1:1</selectitem>
                    <selectitem value="4:3">4:3</selectitem>
                    <selectitem value="16:9">16:9</selectitem>
                    <selectitem value="3:4">3:4</selectitem>
                    <selectitem value="9:16">9:16</selectitem>
                  </selectcontent>
                </select>

                <button onclick="{handleGenerateImage}" disabled classname="flex-shrink-0 bg-gradient-to-r from-indigo-500 to-purple-600 hover:from-indigo-600 hover:to-purple-700 text-white font-semibold py-2 px-4 rounded-full transition-all duration-300 ease-in-out transform hover:scale-105">
                 {isLoading ? "Generating..." : "Generate Image"}
                </button>
              </div>
            </textarea>
</div>
          </div>
          <separator orientation="vertical" classname="hidden md:block"></separator>
          <div classname="w-full md:w-1/2 p-6 bg-gray-50/50 flex flex-col">
            <h2 classname="text-3xl font-bold mb-6 text-gray-800 bg-clip-text text-transparent bg-gradient-to-r from-purple-500 to-pink-600">
              Generated Image
            </h2>
            {imageUrl ? (
              <motion.div initial="{{" opacity: scale: animate="{{" transition="{{" duration: classname="flex-grow flex flex-col items-center justify-center">
                <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/172896621558474.jpg?x-oss-process=image/resize,p_40" class="lazy" ref="{imageRef}" alt="Generated" classname="max-w-full max-h-[60vh] object-contain rounded-lg shadow-lg mb-6">
                <div classname="flex space-x-4">
                  <button onclick="{handleDownloadImage}" classname="rounded-full bg-gradient-to-r from-purple-500 to-pink-600 hover:from-purple-600 hover:to-pink-700 text-white font-semibold py-2 px-4 transition-all duration-300 ease-in-out transform hover:scale-105 flex items-center space-x-2">
                    {downloading ? "Downloading..." : <downloadicon></downloadicon>}
                    <span>Download</span>
                  </button>
                </div>
              </motion.div>
            ) : (
              <div classname="flex-grow flex items-center justify-center text-gray-400">
                <p classname="text-lg italic">
                  Your generated image will appear here
                </p>
              </div>
            )}
          </div>
        </div>
      </motion.div>
    </div>
  );
}

export default App;
</htmlimageelement>

Build a Free AI Image Generator with ReactJS

Build a Free AI Image Generator with ReactJS

最後的想法

透過此設置,您現在擁有一個簡單的 ReactJS 應用程序,可以產生和下載 AI 生成的圖像。
感謝您的閱讀!如果您覺得這篇文章有趣,請不要猶豫,按個讚。快樂編碼!

以上是使用 ReactJS 建立免費的 AI 圖像生成器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn