简体   繁体   中英

Using PngBitmapDecoder, MemoryStream, FlowDocument, XPSDocument to Preview Images

I'm not quite sure what's happening, so I apologize if the title isn't specific. I've provided the code and xaml below which demonstrates my problem. I have the static methods that I call to convert bitmap to byte [] and vice versa. These methods work fine when used to bind source to image control. However, when I use them to assign a source to images which are children of BlockUIContainer as the code demostrates... I get the same image as the previous on my second call to ByteArrayToBitmapSource.

I'm clueless. What is obvious to me, however, is that the second image has the properties of the image that I expect it display, but is apparently the wrong image.

C# MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Drawing.Imaging;
using System.Drawing;
using System.Windows.Xps.Packaging;
using System.Windows.Xps;

namespace FlowDocumentTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, IDisposable
    {
        private XpsDocument xpsDocument;
        private String randomFileName;

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            FlowDocument doc = new FlowDocument();

            doc.Blocks.Add(new Paragraph(new Run("Test")));

            Section section1 = new Section();
            BlockUIContainer blockUIContainer1 = new BlockUIContainer();
            blockUIContainer1.Child = new System.Windows.Controls.Image { Source = Source1 };

            Section section2 = new Section();
            BlockUIContainer blockUIContainer2 = new BlockUIContainer();
            blockUIContainer2.Child = new System.Windows.Controls.Image { Source = Source2 };

            doc.Blocks.Add(blockUIContainer1);
            doc.Blocks.Add(blockUIContainer2);

            randomFileName = System.IO.Path.GetRandomFileName();

            this.xpsDocument = new XpsDocument(randomFileName, System.IO.FileAccess.ReadWrite);

            XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
            writer.Write(((IDocumentPaginatorSource)doc).DocumentPaginator);

            this.Viewer.Document = xpsDocument.GetFixedDocumentSequence();
        }

        public BitmapSource Source1
        {
            get
            {
                byte[] tmp = BitmapSourceToByteArray(GetBitmapImage(new Bitmap(@"source1.jpg")));
                return ByteArrayToBitmapSource(tmp);
            }
        }

        public BitmapSource Source2
        {
            get
            {
                byte[] tmp = BitmapSourceToByteArray(GetBitmapImage(new Bitmap(@"source2.bmp")));
                return ByteArrayToBitmapSource(tmp);
            }
        }

        public static BitmapImage GetBitmapImage(Bitmap bitmap)
        {
            BitmapImage bitmapImage = new BitmapImage();
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Png);
                stream.Position = 0;
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = stream;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
            }
            return bitmapImage;
        }

        public static byte[] BitmapSourceToByteArray(BitmapSource bitmapSource)
        {
            byte[] data;
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmapSource));

            using (MemoryStream ms = new MemoryStream())
            {
                encoder.Save(ms);
                data = ms.ToArray();
            }
            return data;
        }

        public static BitmapSource ByteArrayToBitmapSource(byte[] data)
        {
            BitmapSource result;
            using (MemoryStream ms = new MemoryStream(data))
            {
                PngBitmapDecoder decoder = new PngBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                result = decoder.Frames[0];
            }
            return result;
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            this.Dispose();
        }

        public void Dispose()
        {
            this.xpsDocument.Close();
            if (System.IO.File.Exists(randomFileName))
                System.IO.File.Delete(randomFileName);  
        }
    }
}

XAML MainWindow.xaml

 <Window x:Class="FlowDocumentTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DocumentViewer Name="Viewer" />
    </Grid>
 </Window>

I guess it has to do with returning a BitmapSource as oppose to a discreet BitmapImage. Created this method and called this method instead, and it works as I expect.

Still don't know whether this is FlowDocument or XPSDocument related issue.

public static BitmapSource GetBitmapImage(Bitmap bitmap)
{
    BitmapImage bitmapImage = new BitmapImage();
    using (MemoryStream stream = new MemoryStream())
    {
        bitmap.Save(stream, ImageFormat.Png);
        stream.Position = 0;
        bitmapImage.BeginInit();
        bitmapImage.StreamSource = stream;
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.EndInit();
    }
    return bitmapImage;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM