前提・実現したいこと
オシロの画像データをVB.NETで取得しようとしています。
オシロメーカーからバイナリデータの出力の仕方は教わったのですが、肝心なその後の画像ファイルにする方法までは教えてくれませんでした。
画像データの拡張子はPNGです。
画像データを扱うのは初めてなので、やり方がさっぱり分からないです。
装置メーカーに画像ファイルの生成方法を聞くのも違うかなと思って、こちらに質問を出させていただきました。
発生している問題
バイナリデータもちゃんと取得できているか分かりませんが、ほかのコマンドで測定値は読めるので、出力されている前提でお願いします。 バイナリデータの取り込み方はいろいろと調べて、「試したこと」に記載したコードは見つけました。 ですが、これをどう使うのかが分かりません。
該当のソースコード
VB.NET
1Private Sub hard_copy_Click(sender As Object, e As EventArgs) Handles hard_cpopy.Click 2 3 SerialPort1.Open() 4 5 SerialPort1.WriteLine("HARDCOPY:PORT RS232") 6 SerialPort1.WriteLine("HARDCOPY:FORMAT PNG") 7 SerialPort1.WriteLine("HARDCOPY START") 'ここからバイナリデータが出力されるとメーカーから教わった 8 9 'ここに下記コードでデータは取得できそうですが、そこからPNGファイルに変換したいです 10 '画像ファイルに変換できるのなら、別の方法でも可です 11 12 SerialPort1.Close() 13 14 End Sub
解決したコード
バイト配列をImageオブジェクトに変換するFunctionを追加しています。
(Web上から見つけました)
VB.NET
1 Private Sub hard_cpopy_Click(sender As Object, e As EventArgs) Handles hard_cpopy.Click 2 SerialPort1.Open() 3 SerialPort1.WriteLine("HARDCOPY:PORT RS232") 4 SerialPort1.WriteLine("HARDCOPY:LAYOUT PORTRAIT") 5 SerialPort1.WriteLine("HARDCOPY:INKS ON") 6 SerialPort1.WriteLine("HARDCOPY:FORMAT TIF") 7 SerialPort1.WriteLine("HARDCOPY START") 8 9 Dim img As Byte() 10 img = ReadBinaryData(SerialPort1) 11 12 Dim img2 As Image = ByteArrayToImage(img) 13 14 img2.Save("hard.tif", System.Drawing.Imaging.ImageFormat.Tiff) 15 16 SerialPort1.Close() 17 18 End Sub 19 20 ' バイト配列をImageオブジェクトに変換 21 Public Shared Function ByteArrayToImage(ByVal b As Byte()) As Image 22 Dim img As Image = CType(imgconv.ConvertFrom(b), Image) 23 Return img 24 End Function 25 26 Public Function ReadBinaryData(st As SerialPort) As Byte() 27 Dim buf(32768) As Byte ' 一時バッファ 28 '無限に待たれても困るので、ReadTimeoutがInfiniteTimeoutならとりあえず10秒に設定 29 If st.ReadTimeout = SerialPort.InfiniteTimeout Then 30 st.ReadTimeout = 10000 31 End If 32 Using ms As New MemoryStream() 33 While (True) 34 Try 35 ' シリアルポートから一時バッファに読み込む 36 Dim read As Integer = st.Read(buf, 0, buf.Length) 37 If read > 0 Then 38 ' 一時バッファの内容をメモリ・ストリームに書き込む 39 ms.Write(buf, 0, read) 40 Else 41 Exit While 42 End If 43 Catch ex As TimeoutException 44 'タイムアウト処理も入れておく 45 Exit While 46 End Try 47 End While 48 ' メモリ・ストリームの内容をバイト配列に格納 49 Return ms.ToArray() 50 End Using 51 End Function
上記のコードで期待するTIFF画像を得ることができました。
課題は10秒待たないとTIFFが得られないこと。
オシロからのTIFFデータの転送終了を知ることが出来れば完璧ですが、とりあえず及第点です。
回答いただいた方、ありがとうございました。
このプロトコルって画像データの終わりはどうやって知るんですかね?
メーカーからは下記の回答を得ています。
「また、RS232のようなインターフェースでは転送の終了を確認する方法がないので
ご注意ください。転送されるデータがASCIIであれば、CRやLFをもって転送終了と
する事もできますが、バイナリデータではそれができません。複数回読み込みを
行っていただき、データがある程度(10秒程度)来ない事を確認して転送の終了と
するのが確実です。」
この文言も理解できていないです。。。
まずは出来るところからと思っています。
タイムアウト処理が必要であれば、ReadTimeout既定値では無限に待ち続けるので適切な値を設定してください。(10秒なら10000)
昨日、保管している装置を確認したのですが、画像保存の形式がPNGに対応していないものもありました。
TIFFなら全部対応していたので、こちらに変更するしかなさそうです。
PNG対応とTIFF対応の2つのコードを書くのは大変そうなので。。。
解決したコードが私の修正したサンプルのコードと同じようですが、ベストアンサーではない理由をお聞かせ願えますか?自力では到達出来なかったコードなのに、及第点とか言われてるのもイラっとするんですが。
不快な思いさせて、すみませんでした。
ベストアンサーにしなかったのは、当初はPNGを想定していたので、その解決法を示してくださった方を選んだためです。
ベストアンサーは一つしか選べなかったので、高評価を付けさせていただきました。
回答3件
あなたの回答
tips
プレビュー