所以我正在创建一个UWP应用程序,需要将文本和图像写入图像文件并保存。我目前已经使用这个源代码在C++中创建了一个D2D包装器,然后是一个C#包装器,它只允许您用漂亮的C#代码访问C++类的函数(它只访问WINMD C++包装器)。
然而,在我们将图像和文本写入流后,我们需要能够使用EXIF头保存文件,其中包含关于旋转和位置的信息。
我们使用encoder.BitmapProperties.SetPropertiesAsync
来实现这一点,但它返回:
Exception thrown: 'System.Exception' in Tester.exe
Additional information: The operation is unsupported. (Exception from HRESULT: 0x88982F81)
没有内部异常,堆栈跟踪为:
at Windows.Graphics.Imaging.BitmapEncoder.get_BitmapProperties()
at Tester.ViewModels.<_SaveImageWithPropertiesAsync>d__56.MoveNext()
我想尽量避免手动添加头,因为我担心D2DContext返回的流不包含任何头信息或其他信息,所以它无法向其添加任何内容。
这是我代码的相关部分:
C++
再次,你可以在这里找到原始来源
IRandomAccessStream^ D2DWrapper::EndDraw()
{
DX::ThrowIfFailed(
m_d2dContext->EndDraw()
);
// If needPreview is true, we return a valid IRandomAccessStream reference.
GUID wicFormat = GUID_ContainerFormatBmp;
ComPtr<IStream> stream;
ComPtr<ISequentialStream> ss;
auto inMemStream = ref new InMemoryRandomAccessStream();
DX::ThrowIfFailed(
CreateStreamOverRandomAccessStream(inMemStream, IID_PPV_ARGS(&stream))
);
SaveBitmapToStream(m_targetBitmap, m_wicFactory, m_d2dContext, wicFormat, stream.Get());
return inMemStream;
}
C#包装
public IRandomAccessStream EndDraw() {
return _context.EndDraw()
}
C#测试仪
async Task _SaveImageWithPropertiesAsync(UWPImaging.Image image, PhotoOrientation photoOrientation)
{
var ras = await image.EndDraw();
var decoder = await BitmapDecoder.CreateAsync(ras);
var file = await KnownFolders.PicturesLibrary.CreateFileAsync(
"test.jpeg",
CreationCollisionOption.GenerateUniqueName);
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
await encoder.BitmapProperties.SetPropertiesAsync(properties); // This is where the error occurs
await encoder.FlushAsync();
}
}
如果能为我们提供帮助,我们将不胜感激!
谢谢,
诺兰
如果目标容器不同(例如JPEG到TIFF),则需要根据目标容器规范在写入元数据之前对其进行修改。WIC资源管理器可以帮助您了解文件的元数据结构。我发现一些编解码器(例如HEIF)在尝试获取所有可用元数据时会冻结应用程序,因此最好手动选择需要的内容。