午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

クリップボードの中にある画像をWPFで取得してみた、Clipboard.GetImage()だけだと透明になる

WPFのClipboardはイマイチな感じで、画像を取得するにはGetImage()を使うんだけど、普通の画像が完全透明になってしまうことがある

透明にならないように取得するには

blogs.yahoo.co.jp

こちらで紹介されているように

Streamに一時保存して読み直すか、問答無用でピクセルフォーマットBgr32に変換する方法が良さそう

 

 

透明になってしまう状態というか画像

これはクリップボードにある画像のbpp(色深度)が関係していて、32bpp未満の画像だと透明になってしまう…きがする、逆に言うと32bppの画像なら問題ない

e-words.jp

 

アプリによってクリップボードにコピーするときの挙動が違って、どんな画像でも32bppに変換するアプリと、そうじゃないアプリがある

 

32bppに変換してコピーするアプリは

変換しないアプリは

 

Microsoft Edgeで表示されている画像をコピーして、GetImage()して表示してみる

f:id:gogowaten:20191112133839p:plain

この前の記事をMicrosoft Edgeで表示して、画像をコピーしているところ、これを

BitmapSource source = Clipboard.GetImage();

 

で取得した画像を表示してみる

f:id:gogowaten:20191112134302p:plain

表示はされているけど完全透明なので何も見えない

 

 

 

32bppに変換してコピーするアプリからなら

f:id:gogowaten:20191112134623p:plain

問題なく取得できるので表示される、こうなってほしい

 

 

 

BitmapSourceクラスのCopyPixels()でピクセルの色の値を見てみる

//bitmapSourceのCopyPixels取得
private byte[] GetPixels(BitmapSource source)
{
    int w = source.PixelWidth;
    int h = source.PixelHeight;
    int stride = w * 4;
    byte[] pixels = new byte[h * stride];
    source.CopyPixels(new Int32Rect(0, 0, w, h), pixels, stride, 0);
    return pixels;
}

GetImageで取得したBitmapSourceをこれに渡す

 

32bppに変換するアプリからだと

f:id:gogowaten:20191112135620p:plain

いいね、ピクセルフォーマットはBgra32なのでアルファの値は[3]、[7]、[11]…のところを見ると、すべて255なので問題なく表示される

 

32bppに変換しないアプリからだと

f:id:gogowaten:20191112135342p:plain

あかん、全て0になっているので、この画像は完全透明

 

 

Streamに一時保存してから読み込む方法

//Streamに一時保存方式、BmpBitmapのエンコーダーとデコーダーを使う
private BitmapSource GetClipboardBitmapEncDec()
{
    BitmapSource source = Clipboard.GetImage();
    if (source == null)
    {
        return null;
    }

    var encoder = new BmpBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(source));
    using (var stream = new System.IO.MemoryStream())
    {
        encoder.Save(stream);
        stream.Seek(0, System.IO.SeekOrigin.Begin);
        var decoder = new BmpBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
        source = decoder.Frames[0];
    }
    return source;
}

これを使って表示すると

 

f:id:gogowaten:20191112142857p:plain

表示された、ピクセルフォーマットがBgr32になっているねえ、それはいいんだけどdpiが中途半端な値になるのが気になる

 

 

ピクセルフォーマットをBgr32へ変換する方法

private BitmapSource GetClipboarBitmapBgr32()
{
    BitmapSource source = Clipboard.GetImage();
    if (source == null) return null;
    return new FormatConvertedBitmap(source, PixelFormats.Bgr32, null, 0);
}

これを使うと

 

f:id:gogowaten:20191112143901p:plain

表示されるし、dpiも96なので、この方法が良さそう

 

クリップボードにある画像のbppを取得したいけど

透明や半透明ピクセルがある画像、つまりアルファの値が255以外の画像もBgr32へ変換してしまうと半透明部分が不透明で表示になってしまうので、そういう画像の場合は変換しないでそのままで取得したい、ってことはクリップボードにある画像のbppが32未満か、そうでないのかを判定する必要がある、でも、GetImage()で取得した時点でピクセルフォーマットはbpp32のBgra32になってしまうので、別の方法で取得する必要がある

 

クリップボードにあるデータのフォーマット形式?

なんかいっぱいあるみたいで、これは

Clipboard.GetDataObject().GetFormats();

ってすると取得できるので一覧を表示する

var formats = Clipboard.GetDataObject().GetFormats();
string name = "";
foreach (var item in formats)
{
    name += Environment.NewLine + item;
}
MessageBox.Show(name);

これで見てみると

 

PrintScreenキーを押したときのクリップボードの中

f:id:gogowaten:20191112145412p:plain

上の3つは普通のBitmapだなあってわかる、4つ目のDeviceIndependentBitmapってのは見慣れない形式だけどBitmapって付いてるから画像っぽい、5つめはさっぱりわからん

 

 

Google Chromeに表示された画像をコピー

f:id:gogowaten:20191112145645p:plain

画像形式もあるけどその他に、ウェブブラウザだからかHTMLってのがある

 

 

Microsoft Edgeで表示されている画像をコピーしたとき

f:id:gogowaten:20191112150545p:plain

随分違うねえ、画像っぽいのはDeviceIndependentBitmapだけ

 

メモ帳の文字列をコピーしたときのなか

f:id:gogowaten:20191112150043p:plain

Localeの以外は文字列関係だねえ、画像はない

 

 

エクセルのセルをコピーしたときの中

f:id:gogowaten:20191112150231p:plain

なんかいっぱいある

 

 

クリップボードからのデータ取得は、このフォーマット形式の名前でもできるみたいで

GetData()にフォーマット形式を文字列で指定する

クリップボードの中にBitmap形式のデータがあるときなら

var source = Clipboard.GetDataObject().GetData("Bitmap") as BitmapSource;

これで取得できる

BitmapSourceなら

var source = Clipboard.GetDataObject().GetData("System.Windows.Media.Imaging.BitmapSource") as BitmapSource;

でも、これで取得できるデータは今までのGetImage()で得られるものと全く同じものみたい

そこで、さっきの見慣れないDeviceIndependentBitmap、Bitmapって付いているから画像なのかと思ったけど、これをGetDataで取得すると、型はMemoryStreamだった

もし画像ならBitmapFrameのCreateでStreamから画像を作れるからって、試したけどこれはエラー

f:id:gogowaten:20191112152200p:plain

 

なんとかBitmapSourceに変換できなかと、"DeviceIndependentBitmap bitmapsource"とかでググっていたら

thomaslevesque.com

をグーグル翻訳して読んでたら、WPFのGetImageはBitmapのファイルヘッダっていう部分を削除して取得してしまうみたい

Bitmapのファイルヘッダをググって

 

ja.wikipedia.org

ここと

algorithm.joho.info

ファイルヘッダはファイルサイズとかフォーマット形式を入れるところみたい

Bitmapはファイルヘッダが先頭にあって、次に情報ヘッダ、次にピクセルの色のデータって並んでいて、情報ヘッダにbppの値が入っているのがわかった

WPFのGetImageは情報ヘッダは取得しているみたいなので、これの確認方法がわかればいい

 

 

dobon.net

ここ!ここ見たらMemoryStreamのToArray()でStreamをbyte型の配列に変換している、こういうのがあってこういうことができるんだなあ

 

できたのがこれ

/// <summary>
/// 透明画像にならないようにクリップボードの画像取得、DeviceIndependentBitmapでToArrayの15番目がbpp、32未満ならBgr32へ変換
/// </summary>
/// <returns></returns>
private BitmapSource GetClipboardBitmapDIB()
{
    var data = Clipboard.GetDataObject();
    if (data == null) return null;
    
    var ms = data.GetData("DeviceIndependentBitmap") as System.IO.MemoryStream;
    if (ms == null) return null;

    //DeviceIndependentBitmapのbyte配列の15番目がbpp、
    //これが32未満ならBgr32へ変換、これでアルファの値が0でも255扱いになって表示される
    byte[] dib = ms.ToArray();
    if (dib[14] < 32)
    {
        return new FormatConvertedBitmap(Clipboard.GetImage(), PixelFormats.Bgr32, null, 0);
    }
    else
    {
        return Clipboard.GetImage();
    }
}

 

GetData("DeviceIndependentBitmap")で得たStreamをToArrayでbyte型の配列にする

配列の15番目の値がbppの値なので32未満なら、ピクセルフォーマットを変換、それ以外はそのままGetImage

これで透明にならないし、半透明部分がある画像も不透明にならずに取得できる

 

 

Microsoft Edgeでコピーした画像の取得

f:id:gogowaten:20191112155335p:plain

透明にならずに取得できた、ピクセルフォーマットは変換されてBgr32

 

 

半透明や透明部分がある画像の取得

f:id:gogowaten:20191112162101p:plain

この画像をPixtack紫陽花でコピーして

f:id:gogowaten:20191112155942p:plain

右下の半透明グラデーションの画像をコピーして

貼り付け

f:id:gogowaten:20191112161857p:plain

半透明なまま取得できた、ピクセルフォーマットもBgra32のまま

 

半透明画像をBgr32にすると

f:id:gogowaten:20191112161943p:plain

半透明が失われてしまった画像になる

 

 

bppの値があるインデックス番号は

Bitmapのファイルヘッダはindex0(先頭)から14まで、情報ヘッダは15からで28にBitmapのbppの値がある、WPFはファイルヘッダを取得しないのでbppの値があるindexは、28-14=14、index14

 

32bppに変換するアプリからの画像

f:id:gogowaten:20191112163409p:plain

index14の値は32

 

32bppに変換しないアプリからの画像の場合

f:id:gogowaten:20191112163737p:plain

24

 

 

1bppの画像

f:id:gogowaten:20191112164129p:plain

ファイルのプロパティ

f:id:gogowaten:20191112164112p:plain

ビットの深さ(bpp)は1

これをJTrimで開いて

f:id:gogowaten:20191112164329p:plain

コピーしたものを取得すると

 

f:id:gogowaten:20191112164411p:plain

bppは4になっていた、32未満なのでBgr32へ変換する、もし変換しないでそのままだと

 

f:id:gogowaten:20191112134302p:plain

これも透明になってしまった

 

ここまででできたなあと思っていたけど、エクセルのセルをコピーしたものは32bppなのに透明になってしまう!

f:id:gogowaten:20191112170942p:plain

グラフも中途半端に透明になる

本当は

f:id:gogowaten:20191112171033p:plain

こうなってほしい

 

  1. GetImage
  2. Streamに一時保存でBmpBitmapEncoderとDecoderを使う
  3. 問答無用でBgr32へ変換
  4. GetData("DeviceIndependentBitmap")で取得したStreamからbppを確認、32未満ならBgr32へ変換、それ以外ならそのままGetImage

 

1番が発端

2番はdpiが変な値になるアルファの値は0のままだけど255のような扱いになるしアルファが255固定

3番はアルファの値は0のままだけど255のような扱いになる

4番は1~3番の問題は解決、普通の画像ならこれでいい、あとはエクセルをなんとかしたい、エクセルの問題は1~3番も同じ

 

 

エクセル判定できた

//エクセルからのコピーなのかを判定、フォーマット形式にEnhancedMetafileがあればエクセル判定
private bool IsExcel()
{
    string[] formats = Clipboard.GetDataObject().GetFormats();
    foreach (var item in formats)
    {
        if(item == "EnhancedMetafile")
        {
            return true;
        }
    }
    return false;
}

フォーマット名にEnhancedMetafileがあったらエクセルと判定することにしているけど、エクセル以外でもEnhancedMetafileを使うアプリはありそうだから誤判定もあり得る

これをさっきのbpp判定と組み合わせて

private BitmapSource GetClipboardBitmapDIBExcel()
{
    var data = Clipboard.GetDataObject();
    if (data == null) return null;

    var ms = data.GetData("DeviceIndependentBitmap") as System.IO.MemoryStream;
    if (ms == null) return null;

    //DeviceIndependentBitmapのbyte配列の15番目がbpp、
    //これが32未満ならBgr32へ変換、これでアルファの値が0でも255扱いになって表示される
    //エクセルからのコピーなのかも判定、そうならBgr32へ変換
    byte[] dib = ms.ToArray();
    if (dib[14] < 32 || IsExcel())
    {
        return new FormatConvertedBitmap(Clipboard.GetImage(), PixelFormats.Bgr32, null, 0);
    }
    else
    {
        return Clipboard.GetImage();
    }
}

こう、

if (dib[14] < 32 || IsExcel())

でbpp32未満かエクセルからのコピーだと判断したら、Bgr32へ変換することにした

 

これでエクセルのグラフも

f:id:gogowaten:20191112174058p:plain

できた

 

セルも

f:id:gogowaten:20191112174201p:plain

できた!これだけできれば十分

 

 

wpf_test2/20191111_クリップボードからの画像が透明 at master · gogowaten/wpf_test2

github.com

 

 

f:id:gogowaten:20191112203920p:plain

<Window x:Class="_20191111_クリップボードからの画像が透明.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_20191111_クリップボードからの画像が透明"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="600">
    <Grid>
    <StackPanel Background="Gray">
      <Button Content="クリップボードのデータ形式一覧表示" Click="ButtonViewFormats_Click"/>
      <Button Content="GetImage()" Click="ButtonGetImage_Click"/>
      <Button Content="GetData(Bitmap)" Click="ButtonGetDataBitmap_Click"/>
      <Button Content="GetData(BitmapSource)" Click="ButtonGetDataBitmapSource_Click"/>
      <Button Content="Streamに一時保存方式、BmpBitmapのエンコーダーとデコーダーを使う" Click="ButtonEncDec_Click"/>
      <Button Content="Bgr32へ変換" Click="ButtonBgr32_Click"/>
      <Button Content="GetData(DeviceIndependentBitmap)のbppで判定、32未満ならBgr32へ変換" Click="ButtonDeviceIndependentBitmap_Click"/>
      <Button Content="GetData(DeviceIndependentBitmap)のbppとエクセル?で判定、32未満ならBgr32へ変換" Click="Button_Click"/>
      <TextBlock Name="MyTextBlock" Text="クリップボードに画像をコピーした状態で上の各ボタンを押す"/>
      <ScrollViewer UseLayoutRounding="True">
        <Image Name="MyImage" Stretch="None"/>
      </ScrollViewer>
    </StackPanel>
    </Grid>
</Window>

 

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;


//エクセルからのコピーはFormatConvertedBitmapでBgr32へ変換で決め打ち
//これだと半透明が失われるけど、それ以外の見た目はそっくりにコピーできる
//APIとFormへの参照を追加してメタファイルから画像取得は手間の割にはいまいちな結果が多い
//他のアプリからの画像コピペで透明画像になってしまうのは
//そのアプリがアルファを持たない画像、つまり24bitでクリップボードにコピーしていて
//WPFでそれを受け取ったときにはBgra32に変換されるんだけど、その変換時にアルファをすべて0にしてしまうからかも
//
//WPFのClipboard.GetImage()はピクセルフォーマットBgra32に変換された画像になる
//元の画像が32bitなら問題ないけど、それ以下だとアルファが0になって完全透明になる画像がある
//これは元画像のbit数を取得して32bit未満なら、ピクセルフォーマットBgr32に変換すればいい
//bit数取得はクリップボードからGetData("DeviceIndependentBitmap")で受け取ったMemoryStreamを
//ToArray()でbyte配列に変換してbyte[14]のデータがbit数なのでこれを確認


namespace _20191111_クリップボードからの画像が透明
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        //データフォーマット一覧表示
        private void ButtonViewFormats_Click(object sender, RoutedEventArgs e)
        {
            var formats = Clipboard.GetDataObject().GetFormats();
            string name = "";
            foreach (var item in formats)
            {
                name += Environment.NewLine + item;
            }
            MessageBox.Show(name);
        }

        private void ButtonGetImage_Click(object sender, RoutedEventArgs e)
        {
            BitmapSource source = Clipboard.GetImage();
            //var neko = GetPixels(source);
            SetImageSource(source);
        }

        private void ButtonGetDataBitmap_Click(object sender, RoutedEventArgs e)
        {
            BitmapSource source = Clipboard.GetData("Bitmap") as BitmapSource;
            SetImageSource(source);
        }

        private void ButtonGetDataBitmapSource_Click(object sender, RoutedEventArgs e)
        {
            //var source = Clipboard.GetData("System.Windows.Media.Imaging.BitmapSource") as BitmapSource;
            var source = Clipboard.GetDataObject().GetData("System.Windows.Media.Imaging.BitmapSource") as BitmapSource;
            SetImageSource(source);
        }

        private void ButtonEncDec_Click(object sender, RoutedEventArgs e)
        {
            //Streamに一時保存方式、BmpBitmapのエンコーダーとデコーダーを使う
            SetImageSource(GetClipboardBitmapEncDec());
        }

        //Streamに一時保存方式、BmpBitmapのエンコーダーとデコーダーを使う
        private BitmapSource GetClipboardBitmapEncDec()
        {
            BitmapSource source = Clipboard.GetImage();
            if (source == null)
            {
                return null;
            }

            var encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(source));
            using (var stream = new System.IO.MemoryStream())
            {
                encoder.Save(stream);
                stream.Seek(0, System.IO.SeekOrigin.Begin);
                var decoder = new BmpBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
                source = decoder.Frames[0];
            }
            return source;
        }

        private void ButtonBgr32_Click(object sender, RoutedEventArgs e)
        {
            SetImageSource(GetClipboarBitmapBgr32());
        }
        private BitmapSource GetClipboarBitmapBgr32()
        {
            BitmapSource source = Clipboard.GetImage();
            if (source == null) return null;
            return new FormatConvertedBitmap(source, PixelFormats.Bgr32, null, 0);
        }


        private void ButtonDeviceIndependentBitmap_Click(object sender, RoutedEventArgs e)
        {
            //bppが32未満ならBgr32、それ以外はBgra32のまま
            SetImageSource(GetClipboardBitmapDIB());
        }

        /// <summary>
        /// 透明画像にならないようにクリップボードの画像取得、DeviceIndependentBitmapでToArrayの15番目がbpp、32未満ならBgr32へ変換
        /// </summary>
        /// <returns></returns>
        private BitmapSource GetClipboardBitmapDIB()
        {
            var data = Clipboard.GetDataObject();
            if (data == null) return null;

            var ms = data.GetData("DeviceIndependentBitmap") as System.IO.MemoryStream;
            if (ms == null) return null;

            //DeviceIndependentBitmapのbyte配列の15番目がbpp、
            //これが32未満ならBgr32へ変換、これでアルファの値が0でも255扱いになって表示される
            byte[] dib = ms.ToArray();
            if (dib[14] < 32)
            {
                return new FormatConvertedBitmap(Clipboard.GetImage(), PixelFormats.Bgr32, null, 0);
            }
            else
            {
                return Clipboard.GetImage();
            }
        }

        //エクセル判定追加
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            SetImageSource(GetClipboardBitmapDIBExcel());
        }
        private BitmapSource GetClipboardBitmapDIBExcel()
        {
            var data = Clipboard.GetDataObject();
            if (data == null) return null;

            var ms = data.GetData("DeviceIndependentBitmap") as System.IO.MemoryStream;
            if (ms == null) return null;

            //DeviceIndependentBitmapのbyte配列の15番目がbpp、
            //これが32未満ならBgr32へ変換、これでアルファの値が0でも255扱いになって表示される
            //エクセルからのコピーなのかも判定、そうならBgr32へ変換
            byte[] dib = ms.ToArray();
            if (dib[14] < 32 || IsExcel())
            {
                return new FormatConvertedBitmap(Clipboard.GetImage(), PixelFormats.Bgr32, null, 0);
            }
            else
            {
                return Clipboard.GetImage();
            }
        }

        //エクセルからのコピーなのかを判定、フォーマット形式にEnhancedMetafileがあればエクセル判定
        private bool IsExcel()
        {
            string[] formats = Clipboard.GetDataObject().GetFormats();
            foreach (var item in formats)
            {
                if (item == "EnhancedMetafile")
                {
                    return true;
                }
            }
            return false;
        }
        //画像を表示と画像のピクセルフォーマットとdpi表示するだけ
        private void SetImageSource(BitmapSource source)
        {
            if (source != null)
            {
                MyImage.Source = source;
                MyTextBlock.Text = "PixelFormats = " + source.Format.ToString() + Environment.NewLine +
                    "DpiX = " + source.DpiX;
            }
            else
            {
                MyImage.Source = null;
                MyTextBlock.Text = "null";
            }
        }

        //bitmapSourceのCopyPixels取得
        private byte[] GetPixels(BitmapSource source)
        {
            int w = source.PixelWidth;
            int h = source.PixelHeight;
            int stride = w * 4;
            byte[] pixels = new byte[h * stride];
            source.CopyPixels(new Int32Rect(0, 0, w, h), pixels, stride, 0);
            return pixels;
        }


        /// <summary>
        /// すべてのピクセルのアルファ値を見て、完全透明な画像ならtrueを返す、ピクセルフォーマットBgra32専用
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private bool IsTransparent(BitmapSource source)
        {
            var pixels = GetPixels(source);

            if (pixels[3] != 0)
            {
                return false;
            }
            ulong alpha = 0;
            for (int i = 3; i < pixels.Length; i += 4)
            {
                alpha += pixels[i];
            }
            if (alpha == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            SetImageSource(ClipboardGetImageFix());
        }
        private BitmapSource ClipboardGetImageFix()
        {
            var data = Clipboard.GetDataObject();
            if (data == null) return null;

            BitmapSource source = Clipboard.GetImage();
            if (source == null) return null;

            if (IsTransparent(source))
            {
                return new FormatConvertedBitmap(source, PixelFormats.Bgr32, null, 0);
            }
            else
            {
                return source;
            }
        }



        //private BitmapSource PngAndOfficeArt()
        //{
        //    var data = Clipboard.GetDataObject();
        //    if (data == null) return null;

        //    var ms = data.GetData("PNG") as System.IO.MemoryStream;
        //    //var ms = data.GetData("PNG+Office Art") as System.IO.MemoryStream;
        //    if (ms == null) return null;
        //    var neko = ms.ToArray();

        //    var source = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
        //    //return source;

        //    int w = source.PixelWidth;
        //    int h = source.PixelHeight;
        //    int stride = w * 4;
        //    byte[] pixels = new byte[h * stride];
        //    source.CopyPixels(new Int32Rect(0, 0, w, h), pixels, stride, 0);
        //    //return BitmapSource.Create(w, h, 96, 96, PixelFormats.Bgra32, null, pixels, stride);
        //    double dpi = (double)570 / 365 * 96;
        //    dpi = 150;
        //    BitmapSource bmp = BitmapSource.Create(w, h, dpi, dpi, PixelFormats.Bgra32, null, pixels, stride);
        //    return bmp;

        //}


        //private BitmapSource Png()
        //{
        //    var data = Clipboard.GetDataObject();
        //    if (data == null) return null;

        //    var ms = data.GetData("PNG") as System.IO.MemoryStream;
        //    if (ms == null) return null;

        //    var source = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
        //    return source;
        //}



        //private BitmapSource CreateBitmapFromDIB(System.IO.MemoryStream ms)
        //{
        //    if (ms == null) return null;

        //    byte[] dibBuffer = new byte[ms.Length];
        //    ms.Read(dibBuffer, 0, dibBuffer.Length);

        //    BITMAPINFOHEADER infoHeader =
        //        BinaryStructConverter.FromByteArray<BITMAPINFOHEADER>(dibBuffer);

        //    const int BITMAPFILEHEADER_SIZE = 14;
        //    byte[] bin = ms.ToArray();
        //    int headerSize = BitConverter.ToInt32(bin, 0);
        //    int pixelSize = bin.Length - headerSize;
        //    int fileSize = BITMAPFILEHEADER_SIZE + bin.Length;

        //    var bmpStm = new System.IO.MemoryStream(fileSize);
        //    var writer = new System.IO.BinaryWriter(bmpStm);

        //    writer.Write(Encoding.ASCII.GetBytes("BM"));
        //    writer.Write(fileSize);
        //    writer.Write(0UI);v
        //}
    }
}
//クリップボードの中にある画像をWPFで取得してみた、Clipboard.GetImage() だけだと透明になる - 午後わてんのブログ
// https://gogowaten.hatenablog.com/entry/2019/11/12/201852

 

 

 2019/11/13追記ここから

ピクセルフォーマットをBgra32からBgr32へ変換しても、アルファの値は変化していなくて0のままだった、Bgr32はアルファの値を無視して255扱いにする感じかなあ、てっきり255で上書きされると思っていた、その勘違い箇所を書き直した

 2019/11/13追記ここまで

 

 

 

関連記事

2年後、スクショアプリで使った

gogowaten.hatenablog.com

 

1年後 

gogowaten.hatenablog.com

 

 

5ヶ月後

 

結局すべてのピクセルのAlphaを判定することにした

 

11日前

gogowaten.hatenablog.com