visual-studiowinui-3win2dwindows-app-sdk

Win2D CanvasBitmap::CreateFromBytes arguments don't match


I'm trying to render an image loaded into a cv::Mat object to an Win2D canvas.

The canvas:

<canvas:CanvasControl Draw="CanvasControlDraw" x:Name="GalleryCanvas" ClearColor="#004400"/>

The drawing function:

void TableContentPage::CanvasControlDraw(
    [[maybe_unused]] winrt::Microsoft::Graphics::Canvas::UI::Xaml::
        CanvasControl const &sender,
    [[maybe_unused]] winrt::Microsoft::Graphics::Canvas::UI::Xaml::
        CanvasDrawEventArgs const &args)
{
  auto session = args.DrawingSession();

  cv::Mat inputImage = cv::imread("image_path.jpg");

  auto device = CanvasDevice::GetSharedDevice();

  winrt::array_view<uint8_t const> view((uint8_t *)inputImage.data,
                                        (uint32_t)inputImage.size.dims());

  const auto format =
      Microsoft::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized;

  auto bitmap =
      winrt::Microsoft::Graphics::Canvas::CanvasBitmap::CreateFromBytes(
          device, view, (int32_t)inputImage.cols, (int32_t)inputImage.rows,
          format);
  session.DrawImage(bitmap);
}

CreateFromBytes produces the following errors:

1>C:\Users\user\project\InterfaceItem.xaml.cpp(108,57): error C2665: 'winrt::Microsoft::Graphics::Canvas::CanvasBitmap::CreateFromBytes': no overloaded function could convert all the argument types
1>C:\Users\user\project\Generated Files\winrt\Microsoft.Graphics.Canvas.h(4284,31): message : could be 'winrt::Microsoft::Graphics::Canvas::CanvasBitmap winrt::Microsoft::Graphics::Canvas::CanvasBitmap::CreateFromBytes(const winrt::Microsoft::Graphics::Canvas::ICanvasResourceCreator &,const winrt::Windows::Storage::Streams::IBuffer &,int32_t,int32_t,const winrt::Windows::Graphics::DirectX::DirectXPixelFormat &)'
1>C:\Users\user\project\InterfaceItem.xaml.cpp(108,57): message : 'winrt::Microsoft::Graphics::Canvas::CanvasBitmap winrt::Microsoft::Graphics::Canvas::CanvasBitmap::CreateFromBytes(const winrt::Microsoft::Graphics::Canvas::ICanvasResourceCreator &,const winrt::Windows::Storage::Streams::IBuffer &,int32_t,int32_t,const winrt::Windows::Graphics::DirectX::DirectXPixelFormat &)': cannot convert argument 2 from 'winrt::array_view<const uint8_t>' to 'const winrt::Windows::Storage::Streams::IBuffer &'
1>C:\Users\user\project\InterfaceItem.xaml.cpp(109,51): message : Reason: cannot convert from 'winrt::array_view<const uint8_t>' to 'const winrt::Windows::Storage::Streams::IBuffer'
1>C:\Users\user\project\InterfaceItem.xaml.cpp(109,51): message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>C:\Users\user\project\Generated Files\winrt\Microsoft.Graphics.Canvas.h(4272,31): message : or       'winrt::Microsoft::Graphics::Canvas::CanvasBitmap winrt::Microsoft::Graphics::Canvas::CanvasBitmap::CreateFromBytes(const winrt::Microsoft::Graphics::Canvas::ICanvasResourceCreator &,winrt::array_view<const uint8_t>,int32_t,int32_t,const winrt::Windows::Graphics::DirectX::DirectXPixelFormat &)'
1>C:\Users\user\project\InterfaceItem.xaml.cpp(108,57): message : 'winrt::Microsoft::Graphics::Canvas::CanvasBitmap winrt::Microsoft::Graphics::Canvas::CanvasBitmap::CreateFromBytes(const winrt::Microsoft::Graphics::Canvas::ICanvasResourceCreator &,winrt::array_view<const uint8_t>,int32_t,int32_t,const winrt::Windows::Graphics::DirectX::DirectXPixelFormat &)': cannot convert argument 5 from 'const winrt::Microsoft::Graphics::DirectX::DirectXPixelFormat' to 'const winrt::Windows::Graphics::DirectX::DirectXPixelFormat &'
1>C:\Users\user\project\InterfaceItem.xaml.cpp(109,61): message : Reason: cannot convert from 'const winrt::Microsoft::Graphics::DirectX::DirectXPixelFormat' to 'const winrt::Windows::Graphics::DirectX::DirectXPixelFormat'
1>C:\Users\user\project\InterfaceItem.xaml.cpp(109,61): message : Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or parenthesized function-style cast)
1>C:\Users\user\project\InterfaceItem.xaml.cpp(108,57): message : while trying to match the argument list '(winrt::Microsoft::Graphics::Canvas::CanvasDevice, winrt::array_view<const uint8_t>, int, int, const winrt::Microsoft::Graphics::DirectX::DirectXPixelFormat)'

I tried calling in a simpler manner, like this,

auto const& formatRef = format;
winrt::Microsoft::Graphics::Canvas::CanvasBitmap bitmap =
    winrt::Microsoft::Graphics::Canvas::CanvasBitmap::CreateFromBytes(
        device, winrt::array_view<uint8_t const>(), 1, 1, formatRef);

With the same result.

Any idea why the parameters don't match?


Solution

  • The code needs an extra cast, so something like this:

    auto bitmap =
      winrt::Microsoft::Graphics::Canvas::CanvasBitmap::CreateFromBytes(
          device, view, (int32_t)inputImage.cols, (int32_t)inputImage.rows,
          (winrt::Windows::Graphics::DirectX::DirectXPixelFormat const&)format);