Chatgpt가 레시피를 추천해주고, 그 레시피이름을 변수에 따로 할당하는 것 까지 진행했다.
이제 이 응답받은 레시피 이름을 가지고 이미지를 출력해줘야하는데 다음과 같은 방법이 있다.
1. 공개적인 온라인 데이터베이스 활용: 음식 사진을 공유하는 사이트나 음식 블로그에서 레시피 이미지를 크롤링, 이러한 이미지를 수집하여 데이터베이스에 저장하고, 레시피 데이터와 연결
2. 온라인 이미지 검색 API 활용: Google 이미지 검색 API나 Bing 이미지 검색 API와 같은 온라인 이미지 검색 API를 활용하여 레시피명을 기반으로 이미지를 검색. 사용자가 레시피를 요청하면 API를 통해 이미지 검색을 실행하고, 해당 이미지들을 데이터베이스에 저장.
3. 레시피 공유 사이트 API 활용: 음식 관련 레시피를 공유하는 사이트의 API를 활용하여 특정 재료에 대한 레시피 정보와 이미지를 가져와서 데이터베이스에 저장.
4. ChatGPT API를 활용: 응답받은 레시피를 받아 ChatGPT 이미지 검색( DallE )
일단 이 앱은 레시피 데이터베이스를 자체적으로 사용하는 것이 아니라, Chatgpt 모델을 사용하는 것이다.
때문에 Chatgpt가 응답할 수 있는 레시피에 대한 데이터가 없고, 아무리 잘 되어 있는 레시피 공유 사이트의 API를 활용하더라도 누락이 생길 수있어 이미지 데이터베이스를 구성하는 것엔 무리가 있다.
그래서 1, 3은 제외하고 먼저 이 게시글에선 4번 방법을 활용한다
https://www.youtube.com/watch?v=MQfVCY9qgEU
레시피 이미지를 보여주기 위해 위 유튜브를 참고하여 ChatGpt API를 활용하여 이미지 검색 기능을 구현한다
https://github.com/srcnalt/OpenAI-Unity
위 깃허브 URL을 Copy하고, 유니티 -> Window -> Package Manager에 들어간다. 큰 +버튼을 누르고 4가지 다운바중
Add Package from github URL을 클릭해 복사한 URL주소를 입력한다. 우리가 필요한건 이미지 검색뿐이므로
DallE만 Import시켜준다. (ChatGPT도 이 깃허브 라이브러리 사용했으면 될텐데, 이전에 이미 OkGODoIT의 깃 자료를 활용했으므로 넘어간다)
임포트하면, JSON 오류가 난다. 이 라이브러리는 이전에 사용한 OkGoDoIt과 다르게 친절하게 Json도 포함되어 있기 때문에 기존에 따로 받아줬던 NewtonSoft.Json.dll파일을 지워줘야 한다. 지워주면 오류가 해결되고, 이제 OpenAI스크립트를 열고 나의 API키를 넣어주면 끝이다
<OpenAI>
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Threading.Tasks;
namespace OpenAI
{
public class DallE : MonoBehaviour
{
[SerializeField] private InputField inputField;
[SerializeField] private Button button;
[SerializeField] private Image image;
[SerializeField] private GameObject loadingLabel;
private OpenAIApi openai = new OpenAIApi("API-KEYS");
private void Start()
{
button.onClick.AddListener(SendImageRequest);
}
private async void SendImageRequest()
{
image.sprite = null;
button.enabled = false;
inputField.enabled = false;
loadingLabel.SetActive(true);
var response = await openai.CreateImage(new CreateImageRequest
{
Prompt = inputField.text,
Size = ImageSize.Size256
});
if (response.Data != null && response.Data.Count > 0)
{
using(var request = new UnityWebRequest(response.Data[0].Url))
{
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Access-Control-Allow-Origin", "*");
request.SendWebRequest();
while (!request.isDone) await Task.Yield();
Texture2D texture = new Texture2D(2, 2);
texture.LoadImage(request.downloadHandler.data);
var sprite = Sprite.Create(texture, new Rect(0, 0, 256, 256), Vector2.zero, 1f);
image.sprite = sprite;
}
}
else
{
Debug.LogWarning("No image was created from this prompt.");
}
button.enabled = true;
inputField.enabled = true;
loadingLabel.SetActive(false);
}
}
}
private OpenAIApi openai = new OpenAIApi("API-KEYS");
난 여기다 바로 키를 넣었지만, 유니티 프로젝트 자체에 Key를 노출하는 것은 좋지 않음.
Json파일로 따로 관리 권장 -자세한 방법은 OpenAIApi 깃허브 ReadMe참고
결과
그런데 몇 번 돌려보니 문제가 있다. 기본적으로는 한글로 입력을 받으면 전혀 이상한 이미지를 출력하고, 레시피를 번역을 해서 입력해도 한식에 대한 이미지는 많이 부족하다. *제육볶음, 김치찌개
구글 콘솔 클라우드의 Google Custom Search JSON API 를 활용하여 개선해보려한다
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Threading.Tasks;
namespace OpenAI
{
public class DallE : MonoBehaviour
{
[SerializeField] private InputField inputField;
[SerializeField] private Button button;
[SerializeField] private Image image;
[SerializeField] private GameObject loadingLabel;
private OpenAIApi openai = new OpenAIApi("API-KEYS");
private void Start()
{
button.onClick.AddListener(SendImageRequest);
}
private async void SendImageRequest()
{
image.sprite = null;
button.enabled = false;
inputField.enabled = false;
loadingLabel.SetActive(true);
var response = await openai.CreateImage(new CreateImageRequest
{
Prompt = inputField.text,
Size = ImageSize.Size256
});
if (response.Data != null && response.Data.Count > 0)
{
using(var request = new UnityWebRequest(response.Data[0].Url))
{
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Access-Control-Allow-Origin", "*");
request.SendWebRequest();
while (!request.isDone) await Task.Yield();
Texture2D texture = new Texture2D(2, 2);
texture.LoadImage(request.downloadHandler.data);
var sprite = Sprite.Create(texture, new Rect(0, 0, 256, 256), Vector2.zero, 1f);
image.sprite = sprite;
}
}
else
{
Debug.LogWarning("No image was created from this prompt.");
}
button.enabled = true;
inputField.enabled = true;
loadingLabel.SetActive(false);
}
}
}