代码之家  ›  专栏  ›  技术社区  ›  Brian Hicks

用C修改xmp数据#

  •  1
  • Brian Hicks  · 技术社区  · 17 年前

    我在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 回复  |  直到 13 年前
        1
  •  1
  •   Chris    17 年前

    这件事怎么样?

    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
  •  1
  •   mckamey    13 年前

    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、big/little endian)。这将补充Chris关于将文件作为一个巨大的字节流读取的答案。

        3
  •  0
  •   Badaro    17 年前

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

        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头不太了解,但如果可能,您应该:

    • 只加载内存中的头
    • 操作内存中的头文件
    • 将标题写入新文件
    • 从原始文件复制其余数据