【问题标题】:Modifying XMP data with C#使用 C# 修改 XMP 数据
【发布时间】:2023-03-06 10:10:02
【问题描述】:

我在 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);

有什么建议吗?

【问题讨论】:

  • 对于您想要实现的目标,我真的认为您不需要将其作为位图读取,您听起来更像是只想操作原始字节对吧?

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


【解决方案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

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

【讨论】:

    【解决方案2】:

    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 规范 2010,第 3 部分,第 12 页)还提供了在扫描字节时要查找的特定字节模式(UTF-8、UTF16、大/小端)。这将补充 Chris 关于将文件作为巨型字节流读取的答案。

    【讨论】:

      【解决方案3】:

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

          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 标头,但如果可能的话,您应该:

      • 仅加载内存中的标头
      • 处理内存中的标头
      • 将标头写入新文件
      • 从原始文件中复制剩余数据

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-02
        • 1970-01-01
        • 1970-01-01
        • 2016-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多