我正在尝试在 JPG 图像上设置没有元数据的元数据。在这种情况下,您不能使用就地编写器(InPlaceBitmapMetadataWriter),因为图像中没有元数据的位置。
如果我使用 FileStream 作为输出 - 一切正常。但如果我尝试使用 MemoryStream 作为输出 - JpegBitmapEncoder.Save() 会引发异常(来自 HRESULT 的异常:0xC0000005)。
经过一番调查后,我还发现如果我提供 null 而不是元数据,什么编码器可以将图像保存到内存流。
我做了一个非常简单且简短的示例来重现该问题:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Media.Imaging;
namespace JpegSaveTest
{
class Program
{
public static JpegBitmapEncoder SetUpMetadataOnStream(Stream src, string title)
{
uint padding = 2048;
BitmapDecoder original;
BitmapFrame framecopy, newframe;
BitmapMetadata metadata;
JpegBitmapEncoder output = new JpegBitmapEncoder();
src.Seek(0, SeekOrigin.Begin);
original = JpegBitmapDecoder.Create(src, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
if (original.Frames[0] != null) {
framecopy = (BitmapFrame)original.Frames[0].Clone();
if (original.Frames[0].Metadata != null) metadata = original.Frames[0].Metadata.Clone() as BitmapMetadata;
else metadata = new BitmapMetadata("jpeg");
metadata.SetQuery("/app1/ifd/PaddingSchema:Padding", padding);
metadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", padding);
metadata.SetQuery("/xmp/PaddingSchema:Padding", padding);
metadata.SetQuery("System.Title", title);
newframe = BitmapFrame.Create(framecopy, framecopy.Thumbnail, metadata, original.Frames[0].ColorContexts);
output.Frames.Add(newframe);
}
else {
Exception ex = new Exception("Image contains no frames.");
throw ex;
}
return output;
}
public static MemoryStream SetTagsInMemory(string sfname, string title)
{
Stream src, dst;
JpegBitmapEncoder output;
src = File.Open(sfname, FileMode.Open, FileAccess.Read, FileShare.Read);
output = SetUpMetadataOnStream(src, title);
dst = new MemoryStream();
output.Save(dst);
src.Close();
return (MemoryStream)dst;
}
static void Main(string[] args)
{
string filename = "Z:\\dotnet\\gnom4.jpg";
MemoryStream s;
s = SetTagsInMemory(filename, "test title");
}
}
}
这是简单的控制台应用程序。
要运行它,请将文件名变量内容替换为任何不带元数据的 .jpg 文件的路径(或使用mine http://lr.gameimg.ru/gnom4.jpg).
Ofc 我可以先将图像保存到临时文件,关闭它,然后打开并复制到 MemoryStream,但它太肮脏且缓慢的解决方法。
欢迎任何关于让它工作的想法:)