Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Neste tutorial, vamos integrar os recursos de geração de imagem do DALL-E em seu aplicativo de desktop WinUI 3 / Windows App SDK.
Prerequisites
- Configure seu computador de desenvolvimento (consulte Começar a desenvolver aplicativos do Windows).
- Uma interface de chat funcional na qual esta capacidade será integrada. Consulte Como adicionar completações de chat OpenAI ao seu aplicativo de desktop WinUI / Windows App SDK - demonstraremos como integrar o DALL-E na interface de chat a partir deste guia de instruções.
- Uma chave de API OpenAI do seu painel de desenvolvedor OpenAI atribuída à
OPENAI_API_KEYvariável de ambiente. - Um SDK OpenAI instalado em seu projeto. Consulte a documentação do OpenAI para obter uma lista de bibliotecas comunitárias. Neste tutorial, usaremos a biblioteca oficial da API OpenAI .NET.
Instalar e inicializar o OpenAI SDK
Certifique-se de que a biblioteca OpenAI .NET está instalada em seu projeto executando dotnet add package OpenAI a partir da janela de terminal do Visual Studio. Inicialize o SDK com sua chave de API OpenAI da seguinte maneira:
//...
using OpenAI;
using OpenAI.Chat;
namespace ChatGPT_WinUI3
{
public sealed partial class MainWindow : Window
{
private OpenAIClient openAiService;
public MainWindow()
{
this.InitializeComponent();
var openAiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
openAiService = new(openAiKey);
}
}
}
Modificar a interface do usuário do seu aplicativo
Modifique o seu DateTemplate no MainWindow.xaml para incluir um controlo Image que exiba imagens na conversa:
<!-- ... existing XAML ... -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Text}" TextWrapping="Wrap" Margin="5" Foreground="{Binding Color}"/>
<Image Source="{Binding ImageUrl}" Margin="5" Stretch="UniformToFill"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<!-- ... existing XAML ... -->
Observe que este tutorial pressupõe que você tenha uma interface de bate-papo com um TextBox e Button; consulte Como adicionar finalizações de bate-papo OpenAI ao seu aplicativo de desktop WinUI 3 / Windows App SDK.
Implementar geração de imagens DALL-E
No seu MainWindow.xaml.cs, adicione os seguintes métodos para lidar com a geração e exibição de imagens:
// ... existing using statements ...
private async void SendButton_Click(object sender, RoutedEventArgs e)
{
ResponseProgressBar.Visibility = Visibility.Visible;
string userInput = InputTextBox.Text;
if (!string.IsNullOrEmpty(userInput))
{
InputTextBox.Text = string.Empty;
// Use the DALL-E 3 model for image generation.
ImageClient imageClient = openAiService.GetImageClient("dall-e-3");
ClientResult<GeneratedImage> imageResult = await imageClient.GenerateImageAsync(userInput,
new ImageGenerationOptions
{
Size = GeneratedImageSize.W1024xH1024,
ResponseFormat = GeneratedImageFormat.Uri,
EndUserId = "TestUser"
});
if (imageResult.Value != null)
{
AddImageMessageToConversation(imageResult.Value.ImageUri);
}
else
{
AddMessageToConversation("GPT: Sorry, something bad happened.");
}
}
ResponseProgressBar.Visibility = Visibility.Collapsed;
}
private void AddImageMessageToConversation(Uri imageUrl)
{
var imageMessage = new MessageItem
{
ImageUrl = imageUrl.ToString()
};
ConversationList.Items.Add(imageMessage);
// handle scrolling
ConversationScrollViewer.UpdateLayout();
ConversationScrollViewer.ChangeView(null, ConversationScrollViewer.ScrollableHeight, null);
}
O imageClient.GenerateImageAsync() método é responsável por chamar a API DALL-E da OpenAI. Consulte os exemplos do OpenAI .NET no GitHub para obter mais exemplos de uso.
Tip
Tente pedir ao Microsoft Copilot algumas sugestões sobre diferentes maneiras de usar as APIs de DALL-E e bate-papo em seu aplicativo.
Note a presença de ImageUrl na classe MessageItem. Este é um novo imóvel:
public class MessageItem
{
public string Text { get; set; }
public SolidColorBrush Color { get; set; }
public string ImageUrl { get; set; } // new
}
Executar e testar
Execute seu aplicativo, insira um prompt e clique no botão "Enviar". Você deve ver algo assim:
Personalizar a interface de utilizador por conta própria
Tente adicionar alguns botões de opção à interface do usuário para selecionar se deseja incluir uma imagem na conversa. Em seguida, pode modificar o método SendButton_Click para chamar condicionalmente o método de geração de imagem com base na seleção do botão de rádio.
Recap
Neste guia, você aprendeu a:
- Aceitar solicitações de imagem de usuários dentro de um
<TextBox>arquivo . - Gere imagens usando a API DALL-E OpenAI.
- Exiba a imagem em um
<Image>.
Arquivos de código completos
Os seguintes são os ficheiros de código completos para a interface de chat com geração de imagens pelo DALL-E. O código foi atualizado para usar botões de opção para chamar condicionalmente o bate-papo ou a geração de imagens, conforme sugerido na seção Personalizar a interface do utilizador por si mesmo acima.
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="ChatGPT_WinUI3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ChatGPT_WinUI3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid VerticalAlignment="Bottom" HorizontalAlignment="Center">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<ScrollViewer x:Name="ConversationScrollViewer" VerticalScrollBarVisibility="Auto" MaxHeight="500">
<ItemsControl x:Name="ConversationList" Width="300">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Text}" TextWrapping="Wrap" Margin="5" Foreground="{Binding Color}"/>
<Image Source="{Binding ImageUrl}" Margin="5" Stretch="UniformToFill"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<ProgressBar x:Name="ResponseProgressBar" Height="5" IsIndeterminate="True" Visibility="Collapsed"/>
<StackPanel Orientation="Vertical" Width="300">
<RadioButtons Header="Query type:">
<RadioButton x:Name="chatRadioButton" Content="Chat" IsChecked="True"/>
<RadioButton x:Name="imageRadioButton" Content="Image"/>
</RadioButtons>
<TextBox x:Name="InputTextBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" KeyDown="InputTextBox_KeyDown" TextWrapping="Wrap" MinHeight="100" MaxWidth="300"/>
<Button x:Name="SendButton" Content="Send" Click="SendButton_Click" HorizontalAlignment="Right"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
using Microsoft.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OpenAI;
using OpenAI.Chat;
using OpenAI.Images;
namespace ChatGPT_WinUI3
{
public class MessageItem
{
public string Text { get; set; }
public SolidColorBrush Color { get; set; }
public string ImageUrl { get; set; }
}
public sealed partial class MainWindow : Window
{
private OpenAIService openAiService;
public MainWindow()
{
this.InitializeComponent();
var openAiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
openAiService = new(openAiKey);
}
private async void SendButton_Click(object sender, RoutedEventArgs e)
{
ResponseProgressBar.Visibility = Visibility.Visible;
string userInput = InputTextBox.Text;
try
{
if (imageRadioButton.IsChecked == true)
{
await ProcessImageRequestAsync(userInput);
}
else
{
await ProcessChatRequestAsync(userInput);
}
}
catch (Exception ex)
{
AddMessageToConversation($"GPT: Sorry, something bad happened: {ex.Message}");
}
finally
{
ResponseProgressBar.Visibility = Visibility.Collapsed;
}
}
private async Task ProcessImageRequestAsync(string userInput)
{
if (!string.IsNullOrEmpty(userInput))
{
InputTextBox.Text = string.Empty;
// Use the DALL-E 3 model for image generation.
ImageClient imageClient = openAiService.GetImageClient("dall-e-3");
ClientResult<GeneratedImage> imageResult = await imageClient.GenerateImageAsync(userInput,
new ImageGenerationOptions
{
Size = GeneratedImageSize.W1024xH1024,
ResponseFormat = GeneratedImageFormat.Uri,
EndUserId = "TestUser"
});
if (imageResult.Value != null)
{
AddImageMessageToConversation(imageResult.Value.ImageUri);
}
else
{
AddMessageToConversation("GPT: Sorry, something bad happened.");
}
}
}
private async Task ProcessChatRequestAsync(string userInput)
{
if (!string.IsNullOrEmpty(userInput))
{
AddMessageToConversation($"User: {userInput}");
InputTextBox.Text = string.Empty;
var chatClient = openAiService.GetChatClient("gpt-4o");
var chatOptions = new ChatCompletionOptions
{
MaxOutputTokenCount = 300
};
var completionResult = await chatClient.CompleteChatAsync(
[
ChatMessage.CreateSystemMessage("You are a helpful assistant."),
ChatMessage.CreateUserMessage(userInput)
],
chatOptions);
if (completionResult != null && completionResult.Value.Content.Count > 0)
{
AddMessageToConversation($"GPT: {completionResult.Value.Content.First().Text}");
}
else
{
AddMessageToConversation($"GPT: Sorry, something bad happened: {completionResult?.Value.Refusal ?? "Unknown error."}");
}
}
}
private void AddImageMessageToConversation(Uri imageUrl)
{
var imageMessage = new MessageItem
{
ImageUrl = imageUrl.ToString()
};
ConversationList.Items.Add(imageMessage);
// handle scrolling
ConversationScrollViewer.UpdateLayout();
ConversationScrollViewer.ChangeView(null, ConversationScrollViewer.ScrollableHeight, null);
}
private void AddMessageToConversation(string message)
{
var messageItem = new MessageItem
{
Text = message,
Color = message.StartsWith("User:") ? new SolidColorBrush(Colors.LightBlue)
: new SolidColorBrush(Colors.LightGreen)
};
ConversationList.Items.Add(messageItem);
// handle scrolling
ConversationScrollViewer.UpdateLayout();
ConversationScrollViewer.ChangeView(null, ConversationScrollViewer.ScrollableHeight, null);
}
private void InputTextBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Enter && !string.IsNullOrWhiteSpace(InputTextBox.Text))
{
SendButton_Click(this, new RoutedEventArgs());
}
}
}
}
Conteúdo relacionado
Windows developer