single.php

C# WinUI3 でクリップボードを利用する方法(画像のコピーと貼り付け)

C# WinUI 3アプリを作っていく途中で、調べたことを忘録的に投稿します。今回はWinUI3プロジェクトで、クリップボードから画像を取得したり、Imageコントロールのデータをクリップボードに転送する方法です。

クリップボードの利用

「コピペ」と略されて、普段のPC作業でも良く使われるWindowsの「クリップボード」。

WinUI3のAPIにも[Clipboard]クラスで利用できます。

クリップボードから画像データを取得

とりあえず、Windowsでよく見る[コピー]と[貼り付け]のコンテキストメニューを作成します。

今回は画像データの転送を行うので結果を確認するために[Image]コントロールを追加しています。

<Grid Width="300" Height="300" Background="White">
  <Grid.ContextFlyout>
    <MenuFlyout>
      <MenuFlyoutItem Text="コピー" Name="CopyMenu" Click="CopyMenu_Click">
        <MenuFlyoutItem.Icon>
          <FontIcon Glyph="&#xE8C8;" />
        </MenuFlyoutItem.Icon>
      </MenuFlyoutItem>
      <MenuFlyoutItem Text="貼り付け" Name="PasteMenu" Click="PasteMenu_Click">
        <MenuFlyoutItem.Icon>
          <FontIcon Glyph="&#xE77F;" />
        </MenuFlyoutItem.Icon>
      </MenuFlyoutItem>
    </MenuFlyout>
  </Grid.ContextFlyout>
  <Image Name="PasteImage" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Uniform" />
</Grid>

[貼り付け]メニューに追加したイベントに、クリップボードからデータを取り出すコードを追加します。

private async void PasteMenu_Click(object sender, RoutedEventArgs e)
{
  DataPackageView dataPackageView = Clipboard.GetContent();
  if (dataPackageView.Contains(StandardDataFormats.Bitmap))
  {
    RandomAccessStreamReference randomAccessstreamReference = await dataPackageView.GetBitmapAsync();
    IRandomAccessStream randomAccessStream = await randomAccessstreamReference.OpenReadAsync();
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.SetSource(randomAccessStream);
    PasteImage.Source = bitmapImage;
  }
}

クリップボードには様々な種類のデータを一時保存できるので[Contains]メソッドでデータの種類を調べてから処理。

また、[IRandomAccessStream]として取得したストリームを[Image]コントロールで表示します。

実行すると、こんな感じでクリップボードにコピーした画像データが[Image]コントロールに表示されます。

クリップボードから画像データを保存

次は[Image]コントロールに表示されている画像データをクリップボードに転送します。

今回はサンプルなので解像度やサイズは適当にしています。

private async void CopyMenu_Click(object sender, RoutedEventArgs e)
{
  RenderTargetBitmap rendertargetBitmap = new RenderTargetBitmap();
  await rendertargetBitmap.RenderAsync(PasteImage);
  IBuffer? pixels = await rendertargetBitmap.GetPixelsAsync();

  InMemoryRandomAccessStream inmemoryrandomaccessStream = new InMemoryRandomAccessStream();
  BitmapEncoder bitmapEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, inmemoryrandomaccessStream);
  bitmapEncoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)rendertargetBitmap.PixelWidth, (uint)rendertargetBitmap.PixelHeight, 96.0, 96.0, pixels.ToArray());

  await bitmapEncoder.FlushAsync();

  RandomAccessStreamReference randomAccessstreamReference = RandomAccessStreamReference.CreateFromStream(inmemoryrandomaccessStream);
  DataPackage dataPackage = new DataPackage();
  dataPackage.SetBitmap(randomAccessstreamReference);
  Clipboard.SetContent(dataPackage);
}

[貼り付け]処理の逆工程になりますが[Image]コントロールから取得したデータをクリップボードを利用するAPIに[RandomAccessStreamReference]として受け渡すためにとに[InMemoryRandomAccessStream]を利用しています。

他にも方法があるかもしれませんが、実行すると[Image]コントロールに表示されている内容がクリップボードに画像データとして転送されます。

まとめ

今回はWinUI3プロジェクトで、クリップボードから画像を取得したり、Imageコントロールのデータをクリップボードに転送する方法について紹介しました。

WinUI3にもクリップボードを利用するための[Clipboard]クラスが用意されているのでテキストや画像などのデータを取得したり、転送が可能です。

WinUI 3アプリでクリップボードに画像を転送したい人の参考になれば幸いです。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です