WebBrowserにPictureBoxの画像を保存せずに表示させるには。

解決


ほろほろ  2005-12-02 01:18:28  No: 93045

VB.NETでGraphicsに描画したグラフをデータと一緒に、WebBrowserコントロールへ一時ファイルを経由せずに表示するプログラムを考えています。

HTMLの方はinnerHTMLに流し込めばいいとわかるのですが、画像をどのように表示させればいいのかがわかりません。
PictureBoxに描画した画像を、一時ファイルを経由せずにWebBrowserで表示する方法を教えてください。


ガッ  2005-12-02 08:50:40  No: 93046

うーん…
VB6のPictureなら、IPersistStreamを使ってIStreamに保存したりできるのは確認しましたが…
VB.NETはちょっと分かりません(orz


魔界の仮面弁士  2005-12-02 10:49:29  No: 93047

Managed WebBrowser (System.Windows.Forms.WebBrowser) の方ならば、
DocumentStream で System.IO.Stream が返されるようなので、
そこに画像を流し込む事ができるかも知れません。試していませんけど。

ActiveX 版の WebBrowser の方だとしたら、IPersistStreamInit インターフェイスの
Load メソッドにて、System.Runtime.InteropServices.UCOMIStream を
渡す事ができますので、これを使って画像のストリームを渡せると思います。


魔界の仮面弁士  2005-12-02 10:55:15  No: 93048

試しに作ってみました。VB.NET 2003 です。
一応動いているようですが、手抜き実装なので保証はしません。(^_^;)


# 問題点があったら、誰か突っ込んでくださいませ。

Imports System.Runtime.InteropServices

================

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    AxWebBrowser1.Navigate("about:blank")
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    'サンプル描画イメージ
    Dim Img As Image = New Bitmap(300, 80)
    Dim G As Graphics = Graphics.FromImage(Img)
    G.FillRectangle(Brushes.Yellow, Img.GetBounds(GraphicsUnit.Pixel))
    Dim F As New Font(Me.Font.FontFamily, 21, FontStyle.Regular)
    G.DrawString(Now.ToString("yyyy/MM/dd HH:mm:ss"), F, Brushes.Red, 0, 0)
    G.Dispose()
    F.Dispose()


    '画像データのJPEGバイナリを取得
    Dim ManagedStream As New System.IO.MemoryStream
    Img.Save(ManagedStream, Imaging.ImageFormat.Jpeg)
    Dim Binary() As Byte
    With New System.IO.BinaryReader(ManagedStream)
        Dim Size As Integer = CInt(ManagedStream.Length)
        ManagedStream.Seek(0, IO.SeekOrigin.Begin)
        Binary = .ReadBytes(Size)
    End With
    ManagedStream.Close()
    Img.Dispose()

    'バイナリをIStreamに変換
    Dim COMStream As UCOMIStream
    Dim ADOStream As New ADODB.StreamClass
    COMStream = DirectCast(ADOStream, UCOMIStream)
    ADOStream.Open()
    ADOStream.Type = ADODB.StreamTypeEnum.adTypeBinary
    ADOStream.Write(Binary)
    ADOStream.Position = 0

    'IPersistStreamInit.Load に渡す
    Dim UnmanagedStream As UCOMIPersistStreamInit
    UnmanagedStream = DirectCast(AxWebBrowser1.Document, UCOMIPersistStreamInit)
    UnmanagedStream.Load(COMStream)

    Marshal.ReleaseComObject(COMStream)
    Marshal.ReleaseComObject(UnmanagedStream)
End Sub

<ComImport(), Guid("0000010c-0000-0000-C000-000000000046"), _
 InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Interface UCOMIPersist
#Region "IPersist"
    Sub GetClassID(ByRef pClassId As Guid)
#End Region
End Interface

<ComImport(), Guid("7FD52380-4E07-101B-AE2D-08002B2EC713"), _
 InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Interface UCOMIPersistStreamInit
    Inherits UCOMIPersist
#Region "IPersist"
    Shadows Sub GetClassID(<Out()> ByRef pClassId As Guid)
#End Region
#Region "IPersistStreamInit"
    <PreserveSig()> Function IsDirty() As <MarshalAs(UnmanagedType.U4)> Boolean
    Sub Load(<[In]()> ByVal pStm As System.Runtime.InteropServices.UCOMIStream)
    Sub Save(<[In]()> ByVal pStm As UCOMIStream, _
        <[In](), MarshalAs(UnmanagedType.Bool)> ByVal fClearDirty As Boolean)
    Sub GetMaxSize(<Out(), MarshalAs(UnmanagedType.LPArray)> ByRef pCbSize As Long)
    Sub InitNew()
#End Region
End Interface


ほろほろ  2005-12-02 15:34:29  No: 93049

魔界の仮面弁士さん、ありがとうございます。

画像自体を渡す方法はわかりました。
しかし、やりたいのはHTMLの中にimgタグで指定してある通常の画像として埋め込む方法なんです。
海外のサイトを見ていても、ストリームからWebBrowserに表示させるサンプルはHTMLだけのものばかりで…


魔界の仮面弁士  2005-12-02 16:43:28  No: 93050

先のコードを実行した場合、HTMLDocumentには、

<HTML><HEAD></HEAD>
<BODY><IMG src="about:blank"></BODY></HTML>

のような DOM として展開されるので、ここから IMG のスタイルや
HTML情報などを、オンメモリで操作する事が可能です。


そういう意味ではなく、<IMG src="★★"> の src にて指定できるようにしたい、
でも、一時ファイルは何らかの事情で使えない……という状況であるのならば、
プロトコルハンドラ("ms-help:"のような)を自作する必要があるでしょうね。


ほろほろ  2005-12-02 18:01:01  No: 93051

実は、考えていたのは後者のほうなんです。
プロトコルハンドラの自作が必要ということは、
システムの設定変更を含めた大掛かりなコーディングが必要になりそうですね…

今回は別の方法を考えたいと思います。
ありがとうございました。


※作成する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。







   このエントリーをはてなブックマークに追加