从多个BitmapImage创建Tiff文件 [英] Create Tiff File from multiple BitmapImage
问题描述
背景:
我正在开发Win 10 Universal App,具有BitmapImage列表:
I'm developing Win 10 Universal App, have list of BitmapImage:
List< BitmapImage>ImagesList = new List< BitmapImage>();
每个列表项都是通过以下代码将 byte []
转换为 BitmapImage
来创建的:
Each list item is created by converting byte[]
to BitmapImage
by this code:
public async Task<BitmapImage> GetBitmapImage(byte[] array)
{
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0)))
{
writer.WriteBytes(array);
await writer.StoreAsync();
}
BitmapImage image = new BitmapImage();
List<BitmapImage> ImagesList = new List<BitmapImage>();
await image.SetSourceAsync(stream);
return image;
}
}
问题:
如何将此列表转换为单个多页Tiff文件?
我找到了许多相关的答案,例如此,但全部基于Windows 10 Universal Apps不支持的 System.Drawing
库,因此,如您在代码中所见,我使用的是 Windows.Ui.Xaml.Media.Imaging.BitmapImage
对象而不是 System.Drawing.Bitmap
对象来获取图像.
I've found many related answers like this but all are based on System.Drawing
library which is not supported in Windows 10 Universal Apps, so as you can see in my code, I'm using Windows.Ui.Xaml.Media.Imaging.BitmapImage
object instead of System.Drawing.Bitmap
to get the image.
推荐答案
如何将此列表转换为单个多页Tiff文件
How to convert this list to single multi-page Tiff file
在UWP应用中,我们可以使用 BitmapEncoder.SetPixelData
方法可用于在一帧上设置像素数据,然后
In UWP app, we can use BitmapEncoder
to encode a Tiff image file to contain several frames. BitmapEncoder.SetPixelData
method can be used for setting pixel data on one frame and then BitmapEncoder.GoToNextFrameAsync
can asynchronously commits the current frame data and appends a new empty frame to be edited. So the Tiff image can be created by multiply images.
假设我想从位于本地文件夹中的三个图像创建一个Tiff图像文件,我解码并读取它们中的像素数据并将其设置为Tiff图像.示例代码如下:
Suppose I want to create a Tiff image file from three images that are located on my local folder, I decode and read pixel data from them and set to the Tiff image. Sample code as follows:
private async void btnConvert_Click(object sender, RoutedEventArgs e)
{
StorageFolder localfolder = ApplicationData.Current.LocalFolder;
StorageFile image1 = await localfolder.GetFileAsync("caffe1.jpg");
StorageFile image2 = await localfolder.GetFileAsync("caffe2.jpg");
StorageFile image3 = await localfolder.GetFileAsync("caffe3.jpg");
StorageFile targettiff = await localfolder.CreateFileAsync("temp.tiff", CreationCollisionOption.ReplaceExisting);
WriteableBitmap writeableimage1;
WriteableBitmap writeableimage2;
WriteableBitmap writeableimage3;
using (IRandomAccessStream stream = await image1.OpenAsync(FileAccessMode.Read))
{
SoftwareBitmap softwareBitmap;
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
softwareBitmap = await decoder.GetSoftwareBitmapAsync();
writeableimage1 = new WriteableBitmap(softwareBitmap.PixelWidth, softwareBitmap.PixelHeight);
writeableimage1.SetSource(stream);
}
using (IRandomAccessStream stream = await image2.OpenAsync(FileAccessMode.Read))
{
SoftwareBitmap softwareBitmap;
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
softwareBitmap = await decoder.GetSoftwareBitmapAsync();
writeableimage2 = new WriteableBitmap(softwareBitmap.PixelWidth, softwareBitmap.PixelHeight);
writeableimage2.SetSource(stream);
}
using (IRandomAccessStream stream = await image3.OpenAsync(FileAccessMode.Read))
{
SoftwareBitmap softwareBitmap;
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
softwareBitmap = await decoder.GetSoftwareBitmapAsync();
writeableimage3 = new WriteableBitmap(softwareBitmap.PixelWidth, softwareBitmap.PixelHeight);
writeableimage3.SetSource(stream);
}
using (IRandomAccessStream ras = await targettiff.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.TiffEncoderId, ras);
var stream = writeableimage1.PixelBuffer.AsStream();
byte[] buffer = new byte[stream.Length];
await stream.ReadAsync(buffer, 0, buffer.Length);
var stream2 = writeableimage2.PixelBuffer.AsStream();
byte[] buffer2 = new byte[stream2.Length];
await stream2.ReadAsync(buffer2, 0, buffer2.Length);
var stream3 = writeableimage3.PixelBuffer.AsStream();
byte[] buffer3 = new byte[stream3.Length];
await stream3.ReadAsync(buffer3, 0, buffer3.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)writeableimage1.PixelWidth, (uint)writeableimage1.PixelHeight, 96.0, 96.0, buffer);
await encoder.GoToNextFrameAsync();
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)writeableimage2.PixelWidth, (uint)writeableimage2.PixelHeight, 96.0, 96.0, buffer2);
await encoder.GoToNextFrameAsync();
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)writeableimage3.PixelWidth, (uint)writeableimage3.PixelHeight, 96.0, 96.0, buffer3);
await encoder.FlushAsync();
}
}
temp.tiff
将成功创建.我不确定您如何获取图像字节数组,但是 BitmapImage 无法直接写入或更新,您需要获取
The temp.tiff
will be created successfully. I'm not sure how you got the image byte array, but BitmapImage cannot be directly written to or updated, you need to got WriteableBitmap object from your byte array. If you don't know how to get the WriteableBitmap
please try to reference the following code or save the BitmapImage
to local folder and using the code I provided above.
public async Task<WriteableBitmap> SaveToImageSource(byte[] imageBuffer)
{
using (MemoryStream stream = new MemoryStream(imageBuffer))
{
var ras = stream.AsRandomAccessStream();
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId, ras);
var provider = await decoder.GetPixelDataAsync();
byte[] buffer = provider.DetachPixelData();
WriteableBitmap ablebitmap = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);
await ablebitmap.PixelBuffer.AsStream().WriteAsync(buffer, 0, buffer.Length);
return ablebitmap;
}
}
更多详细信息,请参考官方示例
这篇关于从多个BitmapImage创建Tiff文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!