【C++/WinRT】ファイルからの画像読み込み
XamlとC++/WinRTを使用してGUIを作る勉強中です。
画像のクラスが複数あるので、それぞれの読み込みと変換方法をメモしておきます。
パターンは以下の3つです。
- 画像をBitmapImageとして読み込む
- 画像をSoftwareBitmapとして読み込む
- 画像を読み込み、ピクセル情報にアクセスする
画像をBitmapImageとして読み込む
メンバ変数のbitmapImageに書き込みます
Windows::Foundation::IAsyncAction MainPage::OpenFileAsBitmapImage_Click(IInspectable const&, RoutedEventArgs const&) { auto lifetime = get_strong(); FileOpenPicker openPicker; openPicker.ViewMode(PickerViewMode::Thumbnail); openPicker.SuggestedStartLocation(PickerLocationId::PicturesLibrary); openPicker.FileTypeFilter().ReplaceAll({ L".jpg", L".jpeg", L".png" }); StorageFile loadedImageFile{ co_await openPicker.PickSingleFileAsync() }; IRandomAccessStream fileStream{ co_await loadedImageFile.OpenAsync(FileAccessMode::Read) }; m_bitmapImage.SetSource(fileStream); }
画像をSoftwareBitmapとして読み込む
メンバ変数のm_softwareBitmapに書き込みます
Windows::Foundation::IAsyncAction MainPage::OpenFileAsSoftwareBitmap_Click(IInspectable const&, RoutedEventArgs const&) { auto lifetime = get_strong(); FileOpenPicker openPicker; openPicker.ViewMode(PickerViewMode::Thumbnail); openPicker.SuggestedStartLocation(PickerLocationId::PicturesLibrary); openPicker.FileTypeFilter().ReplaceAll({ L".jpg", L".jpeg", L".png" }); StorageFile loadedImageFile{ co_await openPicker.PickSingleFileAsync() }; IRandomAccessStream fileStream = co_await loadedImageFile.OpenAsync(FileAccessMode::Read); BitmapDecoder decoder { co_await BitmapDecoder::CreateAsync(fileStream)}; m_softwareBitmap = co_await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat::Bgra8, BitmapAlphaMode::Premultiplied); }
画像を読み込み、ピクセル情報にアクセスする
StorageFileを開いたのちにピクセル情報にアクセスします。 最終的にメンバ変数のm_writeableBitmapに書き込みます。
Windows::Foundation::IAsyncAction MainPage::OpenFileAsPixel_Click(IInspectable const&, RoutedEventArgs const&) { auto lifetime = get_strong(); uint32_t scaledSize = 300; m_writeableBitmap = Imaging::WriteableBitmap(scaledSize, scaledSize); FileOpenPicker openPicker; openPicker.ViewMode(PickerViewMode::Thumbnail); openPicker.SuggestedStartLocation(PickerLocationId::PicturesLibrary); openPicker.FileTypeFilter().ReplaceAll({ L".jpg", L".jpeg", L".png" }); StorageFile loadedImageFile = co_await openPicker.PickSingleFileAsync(); IRandomAccessStream fileStream{ co_await loadedImageFile.OpenAsync(Windows::Storage::FileAccessMode::Read) }; BitmapDecoder decoder{ co_await BitmapDecoder::CreateAsync(fileStream) }; // Scale the image to the appropriate size. Windows::Graphics::Imaging::BitmapTransform transform; transform.ScaledWidth(scaledSize); transform.ScaledHeight(scaledSize); Windows::Graphics::Imaging::PixelDataProvider pixelData{ co_await decoder.GetPixelDataAsync( Windows::Graphics::Imaging::BitmapPixelFormat::Bgra8, // WriteableBitmap uses BGRA format Windows::Graphics::Imaging::BitmapAlphaMode::Straight, transform, Windows::Graphics::Imaging::ExifOrientationMode::IgnoreExifOrientation, // This sample ignores Exif orientation Windows::Graphics::Imaging::ColorManagementMode::DoNotColorManage ) }; winrt::com_array<uint8_t> sourcePixels{ pixelData.DetachPixelData() }; auto bufferByteAccess{ m_writeableBitmap.PixelBuffer().as<::IBufferByteAccess>() }; uint8_t* pTargetBytes{ nullptr }; bufferByteAccess->Buffer(&pTargetBytes); for (auto& element : sourcePixels) { *(pTargetBytes++) = element; } ImageElement().Source(m_writeableBitmap); }