我看到了一些关于如何从图像中读取元数据的问题,但我还没有看到很多人在询问如何编写元数据。基本上,我需要将一个元数据项(“ImageDescription”)添加到我正在动态生成的PNG图像中(创建一个Bitmap对象并在程序上生成其中的所有内容)。
在将文件写入磁盘之前或之后,使用.NET向图像添加元数据的最佳方法是什么?
答案 0 :(得分:1)
你可以使用FreeImage.NET library,我认为它可以读取和写入PNG文件,以及它们的元数据。
答案 1 :(得分:0)
您可以使用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
答案 2 :(得分:0)
需要将一些简单的元数据至少写入.png和.jpg中,而不必将另一个第三方库拖到我的程序中。几个小时后似乎什么都没用,即使所有文件类型都不一样,等等。
仅考虑将图像存储在图像旁边,或者保留文件和所需数据的小型“数据库”。
对我来说,重新加载图像时我只是再次需要数据。数据具有转换系数,可以告诉我多少像素= 1毫米。
剧透 ...如果您不喜欢黑客,请立即关闭。
基本上在文件的末尾,我用二进制“ @ Conv =”编写,然后是该值的8个字节的两倍。
我的程序以二进制读取的形式打开图像...搜寻末尾,然后减去我的“ hack”中的总字节数,并查找“ @ Conv =“。如果找到此值,它将读取值。然后,该程序可以选择确定比例因子后进行保存,而不必每次打开时都进行测量和输入值。
我有读取/查询,更新和添加数据的代码。
与.png,.jpg以及其他类型的字体配合得很好。
我要复制的文件是本地文件。显然,如果从其他应用程序重写文件,则数据将丢失,但是对于许多应用程序而言,任何元数据都可能是正确的。
我最终存储了一些数据项,包括“原始”位置(以像素为单位)和图像的首选旋转角度(0,90,180,270)。
一些vbcode只是用来踢球的。
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