Nos últimos anos, com a evolução da IA, várias ferramentas e serviços surgiram. Como parte da utilização dessas tecnologias a partir do Emacs, anteriormente implementei uma extensão do Emacs para geração de texto usando a API da OpenAI. Essa extensão ainda é amplamente utilizada, mas não suportava a geração de imagens. No entanto, a própria API da OpenAI oferece um modelo e API para geração de imagens. Nesta ocasião, usaremos isso para enriquecer ainda mais a nossa experiência no GNU Emacs.
A API de geração de imagens da OpenAI gera imagens com base em textos fornecidos. Neste caso, utilizaremos o modelo "DALL-E 3". Para começar, vamos verificar o funcionamento da API de geração de imagens.
Aqui está um exemplo de requisição para chamar o endpoint de geração de imagens da OpenAI.
:ORIGIN = https://api.openai.com
:API_KEY := openai-api-key
POST :ORIGIN/v1/images/generations
Content-Type: application/json
Authorization: Bearer :API_KEY
{
"model": "dall-e-3",
"prompt": "pretty cat",
"n": 1,
"size": "1024x1024"
}
{
"created": 1729945494,
"data": [
{
"revised_prompt": "Create an image",
"url": "https://example.com/DUMMY/img-NIXf.png?st=DUMMY&se=DUMMY&sp=r&sv=DUMMY&sr=DUMMY&rscd=inline&rsct=image/png&skoid=DUMMY&sktid=DUMMY&skt=DUMMY&ske=DUMMY&sks=DUMMY&skv=DUMMY&sig=DUMMY"
}
]
}
// POST DUMMY/v1/images/generations
// HTTP/1.1 200 OK
// Date: Sat, 26 Oct 2024 12:24:54 GMT
// Content-Type: application/json
// Content-Length: 1140
// Connection: keep-alive
// openai-version: 2020-10-01
// access-control-allow-origin: *
Ao enviar essa requisição, a API retorna uma resposta JSON que inclui a URL da imagem gerada. O campo data.url contém a URL da imagem gerada, e você pode acessá-la para fazer o download da imagem.
Vamos escrever um código em Emacs Lisp para gerar imagens usando esta API.
;;; openai-image --- OpenAI API Imaging Utility -*- lexical-binding: t -*-
;; Copyright (C) 2024 TakesxiSximada
;; Author: TakesxiSximada <[email protected]>
;; Maintainer: TakesxiSximada <[email protected]>
;; Repository:
;; Version: 1
;; Package-Version: 20241027.0000
;; Package-Requires: ((emacs "28.0")
;; Date: 2024-10-27
;; This file is not part of GNU Emacs.
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;; https://platform.openai.com/docs/api-reference/images/create
;;
;; Request
;;
;; curl https://api.openai.com/v1/images/generations \
;; -H "Content-Type: application/json" \
;; -H "Authorization: Bearer $OPENAI_API_KEY" \
;; -d '{
;; "model": "dall-e-3",
;; "prompt": "A cute baby sea otter",
;; "n": 1,
;; "size": "1024x1024"
;; }'
;;
;; Response
;;
;; {
;; "created": 1589478378,
;; "data": [
;; {
;; "url": "https://..."
;; },
;; {
;; "url": "https://..."
;; }
;; ]
;; }
;;; Code:
(defvar openai-image-previous-ai-prompt "")
;;;###autoload
(defun openai-image-create-and-view (ai-prompt)
(interactive
(list (string-trim (read-string-from-buffer "Open AI Image"
openai-image-previous-ai-prompt))))
(when (not (string-empty-p ai-prompt))
(setq openai-image-previous-ai-prompt ai-prompt)
(make-process :name "*Open AI Image*"
:buffer (generate-new-buffer "*Open AI Image*")
:command `("curl" "https://api.openai.com/v1/images/generations"
"-X" "POST"
"-H" "Content-Type: application/json"
"-H" ,(format "Authorization: Bearer %s" openai-api-key)
"-d" ,(json-encode `(:model "dall-e-3" :n 1 :size "1024x1024" :prompt ,ai-prompt)))
:sentinel (lambda (process event)
(when (string-equal event "finished\n")
(let ((resp (with-current-buffer (process-buffer process)
(goto-char 0)
(json-parse-buffer))))
(eww (gethash "url" (aref (gethash "data" resp) 0)))))))))
(provide 'openai-image)
;; openai-image.el ends here
openai-image.el
Neste bloco de código, estamos gerando uma imagem através da API da OpenAI e acessando a URL da imagem que está contida na resposta usando o eww.
O Emacs possui várias maneiras de enviar requisições HTTP1. Nesta implementação, utilizamos `make-process` para chamar o curl como um subprocesso. Embora seja uma abordagem bastante primitiva, ela evita que você se perca nos labirintos do Emacs Lisp, pois apenas utiliza funções básicas do Emacs.
O prompt (a string que será passada para a IA) é configurado para que a última solicitação serva como o valor padrão. Assim, você poderá ajustar a string para gerar a imagem da maneira que desejar.
Usamos o modelo de geração de imagens da OpenAI, "DALL-E 3", para gerar imagens a partir do GNU Emacs. Especificamente, implementamos um Emacs Lisp que chama a API usando curl e exibe a URL da imagem gerada. Também foram feitas considerações para a configuração inicial do prompt e ajustes nas imagens geradas. Isso facilita a criação de várias imagens. Minha experiência com o GNU Emacs ficou ainda mais enriquecida.
url-retrieve, request.el e plz, embora request.el e plz não sejam bibliotecas padrão.