我有两个功能:在PNG文件中写入和读取元数据。这是CDN的MSDN示例的适应性。没有错误,但没有写入任何内容(也请使用tweakpng工具检查)。我发现需要JPG填充,但PNG没有这样的信息。这段代码有什么问题? (我尝试了其他MetaKey
值,也带有“/ Text / ...”前缀,没有成功。我也尝试读取现有的“key”(添加了tweakpng工具) - 没有(null)。我看到了MSDN示例之一,注释此代码不起作用,但没有其他示例......代码:
open System.IO
open System.Text
open System.Security.Cryptography
open System.Windows.Media.Imaging
let MetaKey = "/tEXt/Description"
let WriteMeta (path : string, a : int, from : b) =
let data = sprintf "%d %d" a b
use stm = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
let dec = new PngBitmapDecoder (stm, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default)
let frm = dec.Frames.[0]
let wr = frm.CreateInPlaceBitmapMetadataWriter ()
let mutable res = false
if wr.TrySave () then
wr.SetQuery (MetaKey, data.ToCharArray())
res <- true
stm.Close ()
res
let ReadMeta (path : string) =
use stm = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
let dec = new PngBitmapDecoder (stm, BitmapCreateOptions.None, BitmapCacheOption.Default)
let met = dec.Frames.[0].Metadata :?> BitmapMetadata
let data = met.GetQuery (MetaKey)
let res =
match data with
| null -> None
| obj -> Some <| obj.ToString ()
stm.Close ()
res
答案 0 :(得分:1)
正如我发现的,由于MSDN文档,这是一个众所周知的问题:它只显示保留元数据但不保存回文件。此代码有效:
let MetaKey = "/tEXt/Description"
let WriteMeta (path : string, data : string) =
let fip = new FileInfo (path)
use stm = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
let dec = new PngBitmapDecoder (stm, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad)
let frm = dec.Frames.[0]
let _met = frm.Metadata
if _met = null then
stm.Close ()
false
else
let met = _met.Clone () :?> BitmapMetadata
stm.Close ()
fip.Delete ()
met.SetQuery (MetaKey, data)
let enc = new PngBitmapEncoder ()
enc.Frames.Add (BitmapFrame.Create (frm, frm.Thumbnail, met, frm.ColorContexts))
use stm' = File.Open (path, FileMode.Create, FileAccess.ReadWrite)
enc.Save (stm')
stm'.Close ()
true
let ReadMeta (path : string) =
use stm = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
let dec = new PngBitmapDecoder (stm, BitmapCreateOptions.None, BitmapCacheOption.Default)
let met = dec.Frames.[0].Metadata :?> BitmapMetadata
if met = null then None
else
let data = met.GetQuery (MetaKey)
let res =
match data with
| null -> None
| obj -> Some <| obj.ToString ()
stm.Close ()
res