A edição de fotos tem se tornado uma área cada vez mais influenciada pelos avanços em inteligência artificial (IA). Com a capacidade de automatizar processos complexos e criar efeitos visuais impressionantes, a IA está revolucionando a maneira como manipulamos imagens. A API da OpenAI, conhecida por suas poderosas ferramentas de machine learning, oferece uma gama de funcionalidades que facilitam a edição e aprimoramento de fotos. Neste artigo, exploraremos como integrar e utilizar essas ferramentas dentro de um ambiente de desenvolvimento .NET.
O que é o Inpainting ?
Inpainting é uma técnica de edição de imagens utilizada para preencher áreas faltantes ou danificadas de uma imagem de maneira que o resultado final pareça natural e sem sinais de alteração. Essa técnica é amplamente utilizada em restauração de fotografias antigas, remoção de objetos indesejados e retoques em geral.
Na prática, o inpainting pode ser realizado manualmente por artistas digitais ou, mais recentemente, por algoritmos de inteligência artificial. Com a IA, o processo se torna automatizado, analisando o contexto ao redor da área a ser preenchida e gerando pixels que se integram perfeitamente com o restante da imagem.
Como funciona o Inpainting da OpenAI?
O endpoint de edição de imagem permite aos usuários carregar uma imagem que deseja editar no formato PNG:
O usuário cria uma máscara que cobre as áreas da imagem que precisam ser substituídas ou editadas. As áreas transparentes da máscara indicam as partes da imagem que devem ser modificadas:
O usuário então fornece um prompt textual que descreve a nova imagem completa, incluindo o contexto geral e os detalhes das áreas a serem editadas. Este prompt ajuda a IA a entender o que deve ser preenchido ou alterado na imagem.
Ex: “Uma área de estar coberta iluminada pelo sol com uma piscina contendo um flamingo.”
E o resultado então é o seguinte:
Aplicações comuns
A técnica de inpainting da OpenAI tem uma ampla gama de aplicações práticas como:
Restauração de fotos antigas: reparar e restaurar partes danificadas ou desbotadas de fotografias antigas, preenchendo áreas desgastadas ou faltantes com detalhes que se integram naturalmente ao resto da imagem.
Remoção de objetos indesejados: eliminar elementos indesejados de fotos, como sinais de trânsito, pessoas ou objetos que atrapalham a composição da imagem, substituindo-os por um fundo realista.
Preenchimento de áreas em fotografias panorâmicas: completar áreas faltantes ou distorcidas em imagens panorâmicas, garantindo uma transição suave e natural entre as diferentes partes da foto.
Correção de imperfeições em fotos de produtos: retocar fotos de produtos para e-commerce, removendo reflexos indesejados, arranhões ou outros defeitos, melhorando a apresentação visual dos produtos.
Essas aplicações demonstram a versatilidade do inpainting da OpenAI, permitindo edições precisas e realistas que podem ser aplicadas em diversos campos.
Criando o projeto de exemplo
Para nossa aplicação de exemplo, vamos criar uma API em ASP.NET Core. Então, crie um projeto Web API e adicione o controller chamado “ImageEditController”. Nele, adicione uma action chamada “EditImage” que receberá três parâmetros: uma string que descreve a edição desejada na imagem, um arquivo de imagem contendo a imagem original, e uma máscara que indica as áreas da imagem a serem editadas. A máscara deve ter as partes a serem editadas removidas, permitindo que a API realize as modificações conforme a descrição fornecida.
Abaixo temos o código inicial desse controller:
using Microsoft.AspNetCore.Mvc;
using System.Net.Http.Headers;
namespace ImageEditingAPI.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class ImageEditController : ControllerBase
{
private static readonly HttpClient client = new HttpClient();
[HttpPost("edit")]
public async Task EditImage(string prompt, IFormFile imagePath, IFormFile maskPath)
{
try
{
// Nosso código
}
catch (Exception ex)
{
return StatusCode(500, $"Erro interno: {ex.Message}");
}
}
}
}
Dentro do bloco “try” vamos armazenar a nossa chave gerada no site da OpenAI na variável “apiKey” para que possamos utilizá-la nas nossas requisições. Em projetos reais é indicado guardar a chave em um local seguro. Caso não saiba como gerar uma chave no site da OpenAI, nós temos um tutorial que ensina desde a criação da conta até a geração da chave.
var apiKey = "Sua_Chave";
Também vamos criar uma variável “n” que indica o número de edições a serem solicitadas. Vamos definir como 2, o que significa que a API deverá retornar duas versões editadas da imagem. O número de imagens a serem geradas deve estar entre 1 e 10.
Além disso, vamos definir uma variável “size” que especifica o tamanho das imagens resultantes. No exemplo, usaremos “1024×1024”. Os tamanhos disponíveis são 256×256, 512×512 ou 1024×1024.
var n = 2;
var size = "1024x1024";
Agora vamos usar a classe MemoryStream para armazenar os dados dos arquivos imagePath (imagem original) e maskPath (máscara). Um MemoryStream é uma stream de dados que armazena os dados na memória, o que é útil para operações de leitura e escrita de dados.
Após copiar os dados para o MemoryStream, o método ToArray() converte os dados do memoryStream em um array de bytes (byte[]) e armazena na variável OriginalImageBytes.
Foi utilizado o procedimento de conversão da imagem em um array de bytes duas vezes no exemplo abaixo para simplificar a demonstração do código. Em uma aplicação real, é recomendável encapsular esse procedimento de conversão em um método auxiliar. Isso melhora a legibilidade, reutilização de código e facilita a manutenção, tornando o código mais organizado e menos propenso a erros.
byte[] OriginalImageBytes;
using (var memoryStream = new MemoryStream())
{
await imagePath.CopyToAsync(memoryStream);
OriginalImageBytes = memoryStream.ToArray();
}
byte[] ImageBytesMask;
using (var memoryStream = new MemoryStream())
{
await maskPath.CopyToAsync(memoryStream);
ImageBytesMask = memoryStream.ToArray();
}
Agora vamos criar uma variável “form” que receberá um objeto do tipo “MultipartFormDataContent”, permitindo a construção de conteúdo multipart/form-data adequado para o envio de dados via HTTP POST. Dentro do objeto “form”, utilizaremos o método “Add” para incluir o prompt, o número de imagens a serem retornadas (n), o tamanho das imagens (size), a imagem original convertida em bytes (identificada como “image.png”) e a máscara da imagem também convertida em bytes (identificada como “mask.png”) na nossa requisição.
var form = new MultipartFormDataContent();
form.Add(new StringContent(prompt), "prompt");
form.Add(new StringContent(n.ToString()), "n");
form.Add(new StringContent(size), "size");
form.Add(new ByteArrayContent(OriginalImageBytes), "image", "image.png");
form.Add(new ByteArrayContent(ImageBytesMask), "mask", "mask.png");
Em seguida, criamos uma instância de “HttpClient” dentro de um bloco “using”, garantindo que os recursos sejam liberados adequadamente após o uso. Utilizamos o método “PostAsync” do “HttpClient” para enviar a requisição POST para o endpoint de edição de imagens da OpenAI, passando o objeto “form” que contém os dados necessários.
Após enviar a requisição, lemos o conteúdo da resposta utilizando “ReadAsStringAsync”. Finalmente, verificamos o status da resposta e tratamos os resultados. Se o código de status for 200, consideramos que a requisição foi bem-sucedida e retornamos um resultado HTTP 200 (Ok) junto com o conteúdo da resposta. Se o código de status indicar um erro (for diferente de 200), retornamos um resultado HTTP 400 (BadRequest) com o conteúdo da resposta, indicando que houve um problema com a requisição.
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
HttpResponseMessage response = await client.PostAsync("https://api.openai.com/v1/images/edits", form);
string responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return Ok(responseContent);
}
else
{
return BadRequest(responseContent);
}
}
Ao executarmos a aplicação é possível enviar uma query, a imagem original e a máscara e receber dois links da imagem editada. As URLs das imagens expiram após 1 hora, portanto, dependendo da aplicação é indicado salvar a imagem.
Abaixo vemos um exemplo de requisição no Swagger utilizando as seguintes imagens:
ImagePath | maskPath |
Formato da resposta:
Imagem 1 e 2 retornadas:
Acelere a sua carreira conosco!
Se você é Desenvolvedor .NET Júnior e quer acelerar sua carreira até nível Pleno com salário de R$7k+, ou mesmo busca a primeira vaga, conheça a Mentoria .NET Start: Clique aqui
Se é Desenvolvedor .NET Pleno ou Sênior e quer virar referência técnica em sua equipe e mercado, com salário de R$10k+, conheça a Mentoria .NET Expert: Clique aqui
Conclusão
A integração da tecnologia de inpainting da OpenAI em aplicações .NET através do ASP.NET Core abre um vasto horizonte de possibilidades na manipulação inteligente de imagens. Este artigo demonstrou como desenvolvedores podem aproveitar essa tecnologia avançada para criar soluções inovadoras que vão desde a restauração de fotos antigas até a remoção de objetos indesejados, tudo de forma automatizada e eficiente.