代码之家  ›  专栏  ›  技术社区  ›  Sukasa

将元数据写入.NET中的PNG图像

  •  5
  • Sukasa  · 技术社区  · 16 年前

    写 元数据。基本上,我需要向动态生成的PNG图像添加一个元数据项(“ImageDescription”)(创建一个Bitmap对象并按程序生成其中的所有内容)。

    2 回复  |  直到 16 年前
        1
  •  1
  •   LBushkin    16 年前

    你可以用这个 FreeImage.NET library

        2
  •  1
  •   edhubbell    7 年前

    可以使用System.Windows.Media.Imaging中的BitmapMetadata写入iTXt值。 VB示例:

    ' Imports System.Windows.Media.Imaging
    ' Imports System.Windows.Media
    
    Dim width = 256
    Dim height = 256
    Dim pngMetadata = New BitmapMetadata("png")
    
    ' PNG spec: http://www.libpng.org/pub/png/book/chapter11.html - Info on the iTXt chunk (and other custom metadata tags). 
    
    pngMetadata.SetQuery("/iTXt/Keyword", "SomeKeyword".ToCharArray())
    pngMetadata.SetQuery("/iTXt/TextEntry", "SomeValue")
    
    Dim bitmap = New WriteableBitmap(width, height, 96, 96, PixelFormats.Gray8, Nothing)
    Dim pixels = New Byte(width * height - 1) {}
    For y = 0 To height - 1
        For x = 0 To width - 1
            pixels(y * width + x) = CByte(x)
        Next
    Next
    
    bitmap.WritePixels(New Int32Rect(0, 0, width, height), pixels, width, 0)
    Dim encoder = New PngBitmapEncoder()
    encoder.Frames.Add(BitmapFrame.Create(bitmap, Nothing, pngMetadata, Nothing))
    
    Using stream = File.Create("c:\pngWithMetaData.png")
        encoder.Save(stream)
    End Using
    
        3
  •  0
  •   TheWhitde    6 年前

    对我来说,我只是在重新加载图像时需要数据。数据包含一个转换因子,它告诉我有多少像素=1mm。

    ... 如果你不喜欢黑客,现在就走开。

    基本上是在我用二进制文件“@Conv=”写的文件的末尾,后跟8字节的双精度值。

    我有代码来读取/查询、更新和添加数据。

    适用于.png、.jpg和其他类型。

    我最终存储了一些数据项,包括图像的“原点”位置(以像素为单位)和首选旋转(0,90180270)。

    Shared arr_magic As Byte() = {CByte(AscW("@"c)), CByte(AscW("C"c)), CByte(AscW("o"c)), CByte(AscW("n"c)), CByte(AscW("v"c)), CByte(AscW("2"c)), CByte(AscW("="c))}
    
    Const metaSize As Integer = 8 + 4 + 4 + 4
    Function FileCheckScale(fn As String, ByRef origin As Point, ByRef angle As Integer, update As Boolean) As Double
        Dim fr = New IO.StreamReader(fn)
    
        Dim br As New IO.BinaryReader(fr.BaseStream)
    
        fr.BaseStream.Seek(-(metaSize + arr_magic.Length), IO.SeekOrigin.End)
    
        For i = 0 To arr_magic.Length - 1
            If br.ReadByte() <> arr_magic(i) Then
                fr.Close()
                Return 0.0 ' <= 0 means not found
            End If
        Next
    
        Dim v As Double = br.ReadDouble
    
        If update Then
            origin.X = br.ReadInt32
            origin.Y = br.ReadInt32
            angle = br.ReadInt32
        End If
    
        fr.Close()
    
        Return v
    End Function
    
    
    Sub FileUpdateScale(fn As String, v As Double, origin As Point, angle As Integer)
        Dim fr = New IO.FileStream(fn, IO.FileMode.Open, IO.FileAccess.Write)
    
        Dim br As New IO.BinaryWriter(fr)
    
        fr.Seek(-(metaSize + arr_magic.Length), IO.SeekOrigin.End)
    
        br.Write(arr_magic)
        br.Write(v)
        br.Write(origin.X)
        br.Write(origin.Y)
        br.Write(angle)
    
        fr.Close()
    End Sub
    
    Sub FileAddScale(fn As String, v As Double, origin As Point, angle As Integer)
        Dim fr = New IO.StreamWriter(fn, True)
        Dim br As New IO.BinaryWriter(fr.BaseStream)
    
        fr.BaseStream.Seek(0, IO.SeekOrigin.End)
    
        br.Write(arr_magic)
        br.Write(v)
        br.Write(origin.X)
        br.Write(origin.Y)
        br.Write(angle)
    
        fr.Close()
    End Sub
    
    推荐文章