2016年12月20日火曜日

VB ICC profile を扱うに当たり msdn ご回答への感謝

似非プログラマー(私)は 本当に どうしょもない です。
でも、 捨てる神あれば 拾う神あり で、 助けて戴ける事もあります。
調べても調べても分からず、 苦肉の策で、 msdn へ 質問 ... 。
お教え戴いた (ご回答をお書き下さった) gekka さまに 感謝!。            code 再掲。.


質問とは ICC profile の 登録名称(正規の説明語句) を取得したい  ... と。

   ICC profile の説明語句の取得について   
   https://social.msdn.microsoft.com/Forums/ja-JP/1fe7ff32-9625-4553-8ca3-6b686c91b038/icc-profile-?forum=wpfja

 
MVP の gekka さま 本当にありがとうございました。.
お陰様で、何とか、プログラミングが進みそうです。


gekka さまに 教えて戴いた 以下の方法で。

msdn での gekka さまのご回答に、 私の お礼返信 投稿 分を反映させた コード (全文)です。


Code Behind  VB.net WPF

Class MainWindow

    Sub New()

        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        'Add by ShiroYuki_Mot
        Dim d_SB As New Text.StringBuilder
        Dim f_inf As IO.FileInfo
        'End Add

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        Dim dlg As Microsoft.Win32.OpenFileDialog = New Microsoft.Win32.OpenFileDialog()
        dlg.Multiselect = True
        dlg.Filter = "ICC,ICM|*.icc;*.icm"
        If dlg.ShowDialog() = True Then

            'Add by ShiroYuki_Mot
            If dlg.FileNames.Count = 0 Then
                Exit Sub
            Else
                f_inf = New IO.FileInfo(dlg.FileName)
                d_SB.Append(f_inf.DirectoryName)
                d_SB.Append(vbCrLf)
                d_SB.Append(dlg.FileNames.Count.ToString)
                d_SB.Append(vbCrLf)
            End If
            'End Add

            For Each path As String In dlg.FileNames
                Dim d = ICC.GetDescription(path)
                System.Diagnostics.Debug.WriteLine(path + vbTab + d.ASCIIInvariantProfile + vbTab + d.UnicodeLocalizableProfile)

                'Add by ShiroYuki_Mot
                f_inf = New IO.FileInfo(path)
                d_SB.Append(f_inf.Name)
                d_SB.Append(Space(6))
                d_SB.Append(d.ASCIIInvariantProfile)
                d_SB.Append(vbCrLf)
                'End Add
            Next
        End If

        'Add by ShiroYuki_Mot
        Me.TextBox1.Text = d_SB.ToString

        'End Add

    End Sub
End Class

Friend Class ICC

    ' http://www.color.org/icc32.pdfを参考

    Public Shared Function GetDescription(ByVal ICC_ICM_FileFullPath As String, Optional ByVal isBOM_BighEndianness As Boolean = True) As Description
        Dim uri As Uri = New Uri("file://" + ICC_ICM_FileFullPath)
        Dim cc = New System.Windows.Media.ColorContext(uri)
        Using stream = cc.OpenProfileStream()
            Dim tags As List(Of Tag) = Tag.GetTags(stream)
            Dim tagDesc = tags.FirstOrDefault(Function(t)
                                                  Return String.Equals(t.signature, "desc")
                                              End Function)
            Dim data As Byte() = tagDesc.GetData(stream)
            Return Description.Decode(data)
        End Using
    End Function

    Private Class BigEndianness

        Public Shared Function ReadInt32(ByVal stream As System.IO.Stream) As Int32
            Dim bs As Byte() = New Byte(3) {}
            stream.Read(bs, 0, 4)
            Array.Reverse(bs)
            Return BitConverter.ToInt32(bs, 0)
        End Function

        Public Shared Function ReadInt32(ByVal buff As Byte(), ByVal index As Integer) As Int32
            Dim bs As Byte() = New Byte(3) {}
            Array.Copy(buff, index, bs, 0, 4)
            Array.Reverse(bs)
            Return BitConverter.ToInt32(bs, 0)
        End Function

        Public Shared Function ReadInt16(ByVal buff As Byte(), ByVal index As Integer) As Int32
            Dim bs As Byte() = New Byte(1) {}
            Array.Copy(buff, index, bs, 0, 2)
            Array.Reverse(bs)
            Return BitConverter.ToInt16(bs, 0)
        End Function

        Public Shared Function ReadString(ByVal stream As System.IO.Stream, ByVal size As Integer) As String
            Dim bs As Byte() = New Byte(size - 1) {}
            stream.Read(bs, 0, size)
            Return System.Text.Encoding.ASCII.GetString(bs).TrimEnd(ChrW(0))
        End Function

        Public Shared Function ReadString(ByVal buff As Byte(), ByVal index As Integer, ByVal size As Integer) As String
            Return System.Text.Encoding.ASCII.GetString(buff, index, size).TrimEnd(ChrW(0))
        End Function

        Public Shared Function ReadUnicode(ByVal buff As Byte(), ByVal index As Integer, ByVal size As Integer, Optional ByVal isBOM_BighEndianness As Boolean = True) As String
            If (size = 0) Then
                Return String.Empty
            End If

            Dim data As Byte() = New Byte(size - 1) {}
            Array.Copy(buff, index, data, 0, size)
            If size >= 2 AndAlso data(0) = &HFF AndAlso data(1) = &HFE Then
                'BOMが間違っているファイルがある…
                If (isBOM_BighEndianness) Then
                    data(0) = &HFE
                    data(1) = &HFF
                End If
            ElseIf Not (size > 2 AndAlso data(0) = &HFE AndAlso data(1) = &HFF) Then
                'BOMがない
                data = New Byte(size + 2 - 1) {}
                Array.Copy(buff, index, data, 2, size)

                If (data(2) <> 0) Then
                    data(1) = &HFE
                    data(0) = &HFF
                Else
                    data(0) = &HFE
                    data(1) = &HFF
                End If
            End If
            Dim ms = New System.IO.MemoryStream(data)
            Dim sr = New System.IO.StreamReader(ms, System.Text.Encoding.Unicode, True)
            Return sr.ReadToEnd().TrimEnd(ChrW(0))
        End Function
    End Class

    Public Class Tag

        Public signature As String

        Public offset As Integer

        Public size As Integer

        Public Shared Function GetTags(ByVal stream As System.IO.Stream) As List(Of Tag)
            Dim buffer As Byte() = New Byte(127) {}
            stream.Seek(&H80, System.IO.SeekOrigin.Begin)
            Dim tags As List(Of Tag) = New List(Of Tag)()
            Dim tagCount As Integer = BigEndianness.ReadInt32(stream)
            With Nothing
                Dim i As Integer = 0
                For _F_4 As Integer = 0 To 1 Step 0
                    If Not (i < tagCount) Then
                        Exit For
                    End If

                    Dim t As Tag = New Tag()
                    t.signature = BigEndianness.ReadString(stream, 4)
                    t.offset = BigEndianness.ReadInt32(stream)
                    t.size = BigEndianness.ReadInt32(stream)
                    tags.Add(t)
                    i += 1

                Next
            End With
            Return tags
        End Function

        Public Function GetData(ByVal stream As System.IO.Stream) As Byte()
            stream.Seek(offset, System.IO.SeekOrigin.Begin)
            Dim bs As Byte() = New Byte(size) {}
            stream.Read(bs, 0, bs.Length)
            Return bs
        End Function
    End Class

    Public Class Description

        Public ASCIIInvariantProfile As String

        Public UnicodeLocalizableProfile As String

        'public string LocalizableMacintoshProfile;
        Public Shared Function Decode(ByVal data As Byte(), Optional ByVal isBOM_BighEndianness As Boolean = True) As Description
            If System.Text.Encoding.ASCII.GetString(data, 0, 4) <> "desc" Then
                Throw New ArgumentException()
            End If

            Dim d As Description = New Description()
            Dim p As Integer = 8
            Dim asciiLength As Integer = BigEndianness.ReadInt32(data, p)
            p += 4
            d.ASCIIInvariantProfile = BigEndianness.ReadString(data, p, asciiLength)
            p += asciiLength
            Dim unicodeLanguageCode As Integer = BigEndianness.ReadInt32(data, p)
            p += 4
            Dim unicodeLength As Integer = BigEndianness.ReadInt32(data, p)
            p += 4
            d.UnicodeLocalizableProfile = BigEndianness.ReadUnicode(data, p, unicodeLength * 2, isBOM_BighEndianness)
            p += unicodeLength * 2
            'int scriptcode = data[p];
            'p += 1;
            'int scriptcodeLength = BigEndianness.ReadInt16(data, p);
            'p += 2;
            'd.LocalizableMacintoshProfile = BigEndianness.ReadString(data, p, scriptcodeLength).TrimEnd('\0'); ;
            Return d
        End Function
    End Class
End Class


xaml

 <Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox x:Name="TextBox1" Margin="0" TextWrapping="Wrap" Text="TextBox"/>
    </Grid>
</Window>


さて、何に使おうとしているのかは、 お正月休みに また 投稿を書こうと思っています。



0 件のコメント:

コメントを投稿