使用C#修改XMP数据

时间:2009-05-26 22:00:40

标签: c# asp.net image-processing xmp

我在ASP.NET版本2中使用C#。我正在尝试打开图像文件,读取(并更改)XMP标头,然后再次将其关闭。我无法升级ASP,所以WIC已经出局了,我只是无法弄清楚如何使用它。

这是我到目前为止所拥有的:

Bitmap bmp = new Bitmap(Server.MapPath(imageFile));

MemoryStream ms = new MemoryStream();

StreamReader sr = new StreamReader(Server.MapPath(imageFile));

*[stuff with find and replace here]*

byte[] data = ToByteArray(sr.ReadToEnd());

ms = new MemoryStream(data);

originalImage = System.Drawing.Image.FromStream(ms);

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

这件事怎么样?

byte[] data = File.ReadAllBytes(path);
... find & replace bit here ...
File.WriteAllBytes(path, data);

另外,我真的建议不要在asp.net进程中使用System.Bitmap,因为它会泄漏内存并且会一次又一次地崩溃/随机失败(甚至MS承认这一点)

以下是MS关于System.Drawing.Bitmap不稳定的原因:

http://msdn.microsoft.com/en-us/library/system.drawing.aspx

“警告: System.Drawing命名空间中的类不支持在Windows或ASP.NET服务中使用。尝试在其中一种应用程序类型中使用这些类可能会产生意外问题,例如服务性能下降和运行时异常。“

答案 1 :(得分:1)

Part 1 of the XMP spec 2012, page 10专门讨论如何在不需要了解周围格式的情况下编辑文件(尽管他们确实建议将此作为最后的手段)。嵌入式XMP数据包如下所示:

<?xpacket begin="■" id="W5M0MpCehiHzreSzNTczkc9d"?>
    ... the serialized XMP as described above: ...
    <x:xmpmeta xmlns:x="adobe:ns:meta/">
    <rdf:RDF xmlns:rdf= ...>
        ...
    </rdf:RDF>
    </x:xmpmeta>
    ... XML whitespace as padding ...
<?xpacket end="w"?>
  

在此示例中,'■'表示   Unicode“零宽度不间断空间   字符“(U + FEFF)用作   字节顺序标记。

(XMP Spec 2010,第3部分,第12页)还提供了在扫描字节时要查找的特定字节模式(UTF-8,UTF16,大/小端)。这将补充Chris关于以巨大字节流的形式读取文件的答案。

答案 2 :(得分:0)

您可以使用以下函数来读取/写入二进制数据:

    public byte[] GetBinaryData(string path, int bufferSize)
    {
        MemoryStream ms = new MemoryStream();
        using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
        {
            int bytesRead;
            byte[] buffer = new byte[bufferSize];
            while((bytesRead = fs.Read(buffer,0,bufferSize))>0)
            {
                ms.Write(buffer,0,bytesRead);
            }
        }
        return(ms.ToArray());
    }

    public void SaveBinaryData(string path, byte[] data, int bufferSize)
    {
        using (FileStream fs = File.Open(path, FileMode.Create, FileAccess.Write))
        {
            int totalBytesSaved = 0;
            while (totalBytesSaved<data.Length)
            {
                int remainingBytes = Math.Min(bufferSize, data.Length - totalBytesSaved);
                fs.Write(data, totalBytesSaved, remainingBytes);
                totalBytesSaved += remainingBytes;
            }
        }
    }

但是,将整个图像加载到内存中会占用相当多的RAM。我对XMP标头知之甚少,但如果可能的话,你应该:

  • 仅加载内存中的标题
  • 操纵内存中的标题
  • 将标题写入新文件
  • 复制原始文件中的剩余数据