从多个BitmapImage创建Tiff文件 [英] Create Tiff File from multiple BitmapImage

查看:63
本文介绍了从多个BitmapImage创建Tiff文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:

我正在开发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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆