이 짧은 자습서에서는 .NET MAUI 앱에서 Image Scaler를 사용하는 샘플을 안내합니다. 시작하기 페이지에서 .NET MAUI를 위한 단계를 완료했는지 확인하세요.
소개
이 샘플에서는 텍스트 생성을 위한 LanguageModel 및 이미지 슈퍼 해상도용 ImageScaler를 비롯한 일부 Windows AI API를 사용하여 이미지의 크기를 조정하고 선명하게 하는 방법을 보여 줍니다. "크기 조정" 단추 중 하나를 클릭하여 이미지 크기를 조정하거나 원래의 크기 조정되지 않은 이미지를 다시 표시하거나 텍스트 프롬프트를 입력하고 "생성" 단추를 클릭하여 텍스트 응답을 생성합니다.
".NET MAUI 앱" 템플릿의 변경 내용은 다음 네 개의 파일로 분할됩니다.
- MauiWindowsAISample.csproj: Windows AI API에 필요한 Windows 앱 SDK 패키지 참조를 추가합니다. 이 참조는 Windows용으로 빌드할 때만 조건부로 설정해야 합니다(자세한 내용은 아래 추가 참고 사항 참조). 이 파일은 Windows에 필요한 TargetFramework도 설정합니다.
- 플랫폼/Windows/MainPage.cs: 공유 MainPage 클래스의 부분 메서드를 구현하여 텍스트 생성 및 이미지 크기 조정 기능을 표시하고 처리합니다.
- MainPage.xaml: 텍스트 생성 및 이미지 크기 조정을 표시하는 컨트롤을 정의합니다.
- MainPage.xaml.cs: Windows 관련 MainPage.cs 구현하는 부분 메서드를 정의합니다.
위에 나열된 두 번째 파일에서 ImageScaler 메서드의 몇 가지 기본 기능을 보여 주는 다음 함수를 찾을 수 있습니다.
private async void DoScaleImage(double scale)
{
// Load the original image
var resourceManager = new Microsoft.Windows.ApplicationModel.Resources.ResourceManager();
var resource = resourceManager.MainResourceMap.GetValue("ms-resource:///Files/enhance.png");
if (resource.Kind == Microsoft.Windows.ApplicationModel.Resources.ResourceCandidateKind.FilePath)
{
// Load as a SoftwareBitmap
var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(resource.ValueAsString);
var fileStream = await file.OpenStreamForReadAsync();
var decoder = await BitmapDecoder.CreateAsync(fileStream.AsRandomAccessStream());
var softwareBitmap = await decoder.GetSoftwareBitmapAsync();
int origWidth = softwareBitmap.PixelWidth;
int origHeight = softwareBitmap.PixelHeight;
SoftwareBitmap finalImage;
if (scale == 0.0)
{
// just show the original image
finalImage = softwareBitmap;
}
else
{
// Scale the image to be the exact pixel size of the element displaying it
if (ImageScaler.GetReadyState() == AIFeatureReadyState.NotReady)
{
var op = await ImageScaler.EnsureReadyAsync();
if (op.Status != AIFeatureReadyResultState.Success)
{
throw new Exception(op.ExtendedError.Message);
}
}
ImageScaler imageScaler = await ImageScaler.CreateAsync();
double imageScale = scale;
if (imageScale > imageScaler.MaxSupportedScaleFactor)
{
imageScale = imageScaler.MaxSupportedScaleFactor;
}
System.Diagnostics.Debug.WriteLine($"Scaling to {imageScale}x...");
int newHeight = (int)(origHeight * imageScale);
int newWidth = (int)(origWidth * imageScale);
finalImage = imageScaler.ScaleSoftwareBitmap(softwareBitmap, newWidth, newHeight);
}
// Display the scaled image. The if/else here shows two different approaches to do this.
var mauiContext = scaledImage.Handler?.MauiContext;
if (mauiContext != null)
{
// set the SoftwareBitmap as the source of the Image control
var imageToShow = finalImage;
if (imageToShow.BitmapPixelFormat != BitmapPixelFormat.Bgra8 ||
imageToShow.BitmapAlphaMode == BitmapAlphaMode.Straight)
{
// SoftwareBitmapSource only supports Bgra8 and doesn't support Straight alpha mode, so convert
imageToShow = SoftwareBitmap.Convert(imageToShow, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
}
var softwareBitmapSource = new SoftwareBitmapSource();
_ = softwareBitmapSource.SetBitmapAsync(imageToShow);
var nativeScaledImageView = (Microsoft.UI.Xaml.Controls.Image)scaledImage.ToPlatform(mauiContext);
nativeScaledImageView.Source = softwareBitmapSource;
}
else
{
// An alternative approach is to encode the image so a stream can be handed
// to the Maui ImageSource.
// Note: There's no "using(...)" here, since this stream needs to be kept alive for the image to be displayed
var scaledStream = new InMemoryRandomAccessStream();
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, scaledStream);
encoder.SetSoftwareBitmap(finalImage);
await encoder.FlushAsync();
scaledImage.Source = ImageSource.FromStream(() => scaledStream.AsStream());
}
}
}
}
샘플 빌드 및 실행
- WindowsAppSDK 샘플 리포지토리를 복제합니다.
- "릴리스/실험적" 분기로 전환합니다.
- Samples/WindowsAIFoundry/cs-maui 폴더로 이동합니다.
- Visual Studio 2022에서 MauiWindowsAISample.sln 엽니다.
- 디버그 도구 모음에 "Windows Machine"이 대상 디바이스로 설정되어 있는지 확인합니다.
- F5 키를 누르거나 디버그 메뉴에서 "디버깅 시작"을 선택하여 샘플을 실행합니다(디버그 메뉴 또는 Ctrl+F5에서 "디버깅하지 않고 시작"을 선택하여 샘플을 디버깅하지 않고 실행할 수도 있습니다).