다음을 통해 공유


이미지 배율 조정기 연습

이 짧은 자습서에서는 .NET MAUI 앱에서 Image Scaler를 사용하는 샘플을 안내합니다. 시작하기 페이지에서 .NET MAUI를 위한 단계를 완료했는지 확인하세요.

소개

이 샘플에서는 텍스트 생성을 위한 LanguageModel 및 이미지 슈퍼 해상도용 ImageScaler를 비롯한 일부 Windows AI API를 사용하여 이미지의 크기를 조정하고 선명하게 하는 방법을 보여 줍니다. "크기 조정" 단추 중 하나를 클릭하여 이미지 크기를 조정하거나 원래의 크기 조정되지 않은 이미지를 다시 표시하거나 텍스트 프롬프트를 입력하고 "생성" 단추를 클릭하여 텍스트 응답을 생성합니다.

".NET MAUI 앱" 템플릿의 변경 내용은 다음 네 개의 파일로 분할됩니다.

  1. MauiWindowsAISample.csproj: Windows AI API에 필요한 Windows 앱 SDK 패키지 참조를 추가합니다. 이 참조는 Windows용으로 빌드할 때만 조건부로 설정해야 합니다(자세한 내용은 아래 추가 참고 사항 참조). 이 파일은 Windows에 필요한 TargetFramework도 설정합니다.
  2. 플랫폼/Windows/MainPage.cs: 공유 MainPage 클래스의 부분 메서드를 구현하여 텍스트 생성 및 이미지 크기 조정 기능을 표시하고 처리합니다.
  3. MainPage.xaml: 텍스트 생성 및 이미지 크기 조정을 표시하는 컨트롤을 정의합니다.
  4. 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());
            }
        }
    }
}

샘플 빌드 및 실행

  1. WindowsAppSDK 샘플 리포지토리를 복제합니다.
  2. "릴리스/실험적" 분기로 전환합니다.
  3. Samples/WindowsAIFoundry/cs-maui 폴더로 이동합니다.
  4. Visual Studio 2022에서 MauiWindowsAISample.sln 엽니다.
  5. 디버그 도구 모음에 "Windows Machine"이 대상 디바이스로 설정되어 있는지 확인합니다.
  6. F5 키를 누르거나 디버그 메뉴에서 "디버깅 시작"을 선택하여 샘플을 실행합니다(디버그 메뉴 또는 Ctrl+F5에서 "디버깅하지 않고 시작"을 선택하여 샘플을 디버깅하지 않고 실행할 수도 있습니다).

참고하십시오