VB.NETでGraphicsに描画したグラフをデータと一緒に、WebBrowserコントロールへ一時ファイルを経由せずに表示するプログラムを考えています。
HTMLの方はinnerHTMLに流し込めばいいとわかるのですが、画像をどのように表示させればいいのかがわかりません。
PictureBoxに描画した画像を、一時ファイルを経由せずにWebBrowserで表示する方法を教えてください。
うーん…
VB6のPictureなら、IPersistStreamを使ってIStreamに保存したりできるのは確認しましたが…
VB.NETはちょっと分かりません(orz
Managed WebBrowser (System.Windows.Forms.WebBrowser) の方ならば、
DocumentStream で System.IO.Stream が返されるようなので、
そこに画像を流し込む事ができるかも知れません。試していませんけど。
ActiveX 版の WebBrowser の方だとしたら、IPersistStreamInit インターフェイスの
Load メソッドにて、System.Runtime.InteropServices.UCOMIStream を
渡す事ができますので、これを使って画像のストリームを渡せると思います。
試しに作ってみました。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
魔界の仮面弁士さん、ありがとうございます。
画像自体を渡す方法はわかりました。
しかし、やりたいのはHTMLの中にimgタグで指定してある通常の画像として埋め込む方法なんです。
海外のサイトを見ていても、ストリームからWebBrowserに表示させるサンプルはHTMLだけのものばかりで…
先のコードを実行した場合、HTMLDocumentには、
<HTML><HEAD></HEAD>
<BODY><IMG src="about:blank"></BODY></HTML>
のような DOM として展開されるので、ここから IMG のスタイルや
HTML情報などを、オンメモリで操作する事が可能です。
そういう意味ではなく、<IMG src="★★"> の src にて指定できるようにしたい、
でも、一時ファイルは何らかの事情で使えない……という状況であるのならば、
プロトコルハンドラ("ms-help:"のような)を自作する必要があるでしょうね。
実は、考えていたのは後者のほうなんです。
プロトコルハンドラの自作が必要ということは、
システムの設定変更を含めた大掛かりなコーディングが必要になりそうですね…
今回は別の方法を考えたいと思います。
ありがとうございました。
| ツイート |
|