DOBON.NETプログラミング道掲示板

■35611 / 親記事)  ブラウザでコピーした透過PNGを貼り付けたい
  
□投稿者/ よっし〜 一般人(1回)-(2024/06/07(Fri) 12:18:00)
  • アイコン環境/言語:[VB.NET2013 Win7] 
    分類:[.NET] 

    お疲れ様です。
    現在ブラウザ上に表示されている画像をフォームのPictureBoxに表示するソフトを作成しております。
    ブラウザに表示されている画像で「画像をコピー」しクリップボード経由で「Dim Img As Image = My.Computer.Clipboard.GetImage()」
    すると背景が真っ黒になります。
    画像が透過PNGの為だと思っておりますが、この画像の背景を白にしてPictureBoxに表示する方法はありませんでしょうか?

    If My.Computer.Clipboard.ContainsImage() Then
    Dim Img As Image = My.Computer.Clipboard.GetImage()
    PictureBox1.Image = Img
    End If

    ちなみに透過PNGブラウザで一旦保存し、そのPNGファイルを加工する方法も行いましたが、クリップボードに送られた段階
    で背景が黒く塗られている様で、うまく行きません。

    Using pngImage As Image = Image.FromFile(pngFilePath)
    Using bmp As New Bitmap(pngImage.Width, pngImage.Height)
    Using g As Graphics = Graphics.FromImage(bmp)
    g.Clear(Color.White)
    g.DrawImage(pngImage, 0, 0, pngImage.Width, pngImage.Height)
    End Using
    bmp.Save(OutputFile, ImageFormat.Png)
    End Using
    End Using

    以上、宜しくお願いいたします。
マルチポストを報告
違反を報告
引用返信 削除キー/
■35612 / ResNo.1)  Re[1]: ブラウザでコピーした透過PNGを貼り付けたい
□投稿者/ 魔界の仮面弁士 大御所(1573回)-(2024/06/07(Fri) 14:13:32)
  • アイコンNo35611に返信(よっし〜さんの記事)
    >「Dim Img As Image = My.Computer.Clipboard.GetImage()」
    > すると背景が真っ黒になります。

    CF_BITMAP が取得されたためでしょう。
    取得フォーマットの問題ですね。


    たとえば、下記を Edge からコピーしてみた場合、
    クリップボードには 6 種類のデータが保持されました。
    https://ascii.jp/img/2021/04/11/3186022/l/33f2a9acb9788a6d.png

    CF_PNG ("PNG") ⇒ 透過のPNG画像(460x460)
    CF_DIBV5 (17) ⇒ 黒背景のデバイス非依存ビットマップ(460x460)
    CF_HTML ("HTML Format") ⇒ img タグ入りのHTML(終端nullあり、CRLF改行)
    ("Chromium internal source URL") ⇒ URL文字列(終端nullあり、改行なし)
    CF_BITMAP (2) ⇒ ビットマップハンドル (HBITMAP)
    CF_DIB (8) ⇒ 黒背景のデバイス非依存ビットマップ(460x460)

    ということで修正案。

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      Dim c = Clipboard.GetDataObject()
      Dim img As Image = Nothing
      If c.GetDataPresent("PNG", False) Then
        Dim o = TryCast(c.GetData("PNG"), System.IO.MemoryStream)
        If o IsNot Nothing Then
          img = Image.FromStream(o)
        End If
      ElseIf c.GetDataPresent(GetType(Image)) Then
        img = DirectCast(c.GetData(GetType(Image)), Image)
      End If
      PictureBox1.Image = img
    End Sub
違反を報告
引用返信 削除キー/
■35613 / ResNo.2)  Re[2]: ブラウザでコピーした透過PNGを貼り付けたい
□投稿者/ よっし〜 一般人(3回)-(2024/06/07(Fri) 15:14:46)
  • アイコン魔界の仮面弁士さん、早速のご教示、有り難うございます。

    一応お教え頂いたソースを新しいプロジェクトにして作成し、
    https://ascii.jp/img/2021/04/11/3186022/l/33f2a9acb9788a6d.png
    をブラウザでコピーし、Buttonを押してみたのですが、
    PictureBox1.Image = img
    で「img」はNohingでした。(画像が取れていない様です)

    で、少し気になったのですが、ブラウザによって動作(内容)は変わるものでしょうか?
    例として同じ「33f2a9acb9788a6d.png」をブラウザ上でコピーしワードパッドに貼って見ました。
    FireFox:背景は白(透過)でペーストされました
    Crome:背景は黒でペーストされました

    お教え頂いたソースでは・・・
    Crome:画像が表示されました
    FireFox:PictureBox1.Image = imgのimgがnothingになりました。

    同じコピーでも形式が変わるって事なのでしょうか??

    以上、宜しくお願いいたします。


違反を報告
引用返信 削除キー/
■35614 / ResNo.3)  Re[3]: ブラウザでコピーした透過PNGを貼り付けたい
□投稿者/ 魔界の仮面弁士 大御所(1574回)-(2024/06/07(Fri) 16:11:01)
  • アイコンNo35613に返信(よっし〜さんの記事)
    > 同じコピーでも形式が変わるって事なのでしょうか??
    クリップボードにデータを送信する処理というのは、
    それぞれのアプリケーションの実装依存になっていますので、
    ブラウザーがによって異なる形式になることは十分にありえます。


    > 例として同じ「33f2a9acb9788a6d.png」をブラウザ上でコピーしワードパッドに貼って見ました。
    これも同様。
    クリップボードには、複数のデータ形式が同時に保持されることが多いですが
    その場合、どの形式を採用するかは、添付先のアプリケーション依存です。
    Excel でも、"形式を選択して貼り付け" というモードがありますよね?

    複数のフォーマットをサポートしているアプリの場合、
    (1) 列挙されたフォーマットのうち、最初の形式を採用
    (2) サポートしている形式に優先度をつけ、優先順位の高いフォーマットを優先
    などの違いが生じることがあります。

    たとえば先の私のサンプルは (2) の実装であり、
    "PNG" 優先、無ければ Image を採用…という処理になっているわけです。


    > https://ascii.jp/img/2021/04/11/3186022/l/33f2a9acb9788a6d.png
    > FireFox:PictureBox1.Image = imgのimgがnothingになりました。
    個人的には、Firefox は苦手なんですよね…。
    Child-Tree 系の掲示板に繋ぐと、全角投稿者名などの cookie が腐ることがあったりするので。
    サイト側の問題だといえばそれまでなんですが。


    それはさておき、相手が Firefox や Internet Explorer ならば
     Dim s = Clipboard.GetFileDropList()
     If s.Count > 0 Then
      PictureBox1.LoadAsync(s(0))
      Return
     End If
    で行けるんじゃないですかね?

    試しに FireFox を再インストールして確認してみたところ、
    Internet Explorer および Firefox の場合は、
    下記の 14 種類の形式がクリップボードに含まれていました。


    【Internet Explorer 11 (Win10 22H2) で画像をコピーした場合】
     #01 "DataObject"
     #02 CFSTR_UNTRUSTEDDRAGDROP (50519)
     #03 "msSourceUrl"
     #04 CF_HDROP (15)
     #05 CFSTR_INETURLW (49483)
     #06 CF_DIB ★黒背景画像
     #07 "HTML Format"
     #08 CF_UNICODETEXT (13)
     #09 CF_TEXT (1)
     #10 "Ole Private Data"
     #11 CF_LOCALE (16)
     #12 CF_OEMTEXT (7)
     #13 CF_BITMAP (2) ★黒背景画像
     #14 CF_DIBV5 (17) ★黒背景画像


    【Firefox (ver 126.0.1 64bit) で画像をコピーした場合】
     #01 "DataObject"
     #02 "text/html"
     #03 "HTML Format"
     #04 "text/_moz_htmlinfo"
     #05 "text/_moz_htmlcontext"
     #06 "application/x-moz-file-promise-url"
     #07 "application/x-moz-file-promise-dest-filename"
     #08 CF_HDROP (15)
     #09 CFSTR_PREFERREDDROPEFFECT (49472)
     #10 "application/x-moz-nativeimage" ※取得できない
     #11 CF_DIBV5 (17) ★黒背景画像
     #12 CF_DIB (8) ★黒背景画像
     #13 "Ole Private Data"
     #14 CF_BITMAP (2) ★黒背景画像


    ※"application/x-moz-nativeimage" の場合に HGLOBAL が NULL となるのはバグらしい?
    https://bugzilla.mozilla.org/show_bug.cgi?id=255686
違反を報告
引用返信 削除キー/
■35615 / ResNo.4)  Re[4]: ブラウザでコピーした透過PNGを貼り付けたい
□投稿者/ よっし〜 一般人(4回)-(2024/06/07(Fri) 17:36:16)
  • アイコン魔界の仮面弁士さん、早速のご教示有り難うございます。

    > それはさておき、相手が Firefox や Internet Explorer ならば
    >  Dim s = Clipboard.GetFileDropList()
    >  If s.Count > 0 Then
    >   PictureBox1.LoadAsync(s(0))
    >   Return
    >  End If
    > で行けるんじゃないですかね?

    本当ですね。普通に表示出来ました。
    ただFireFoxはいけましたが、CromeやEdgeも対象としたいので、先にご教示頂きました
     Dim c = Clipboard.GetDataObject()
      Dim img As Image = Nothing
      If c.GetDataPresent("PNG", False) Then
        Dim o = TryCast(c.GetData("PNG"), System.IO.MemoryStream)
        If o IsNot Nothing Then
          img = Image.FromStream(o)
        End If
      ElseIf c.GetDataPresent(GetType(Image)) Then
        img = DirectCast(c.GetData(GetType(Image)), Image)
      End If
      PictureBox1.Image = img
    との合わせ技で解決出来そうです。
    長い間悩んでおりました。どうも有り難うございました。


解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -