使用 PngBitmapDecoder、MemoryStream、FlowDocument、XPSDocument 预览图像 [英] Using PngBitmapDecoder, MemoryStream, FlowDocument, XPSDocument to Preview Images

查看:25
本文介绍了使用 PngBitmapDecoder、MemoryStream、FlowDocument、XPSDocument 预览图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不太确定发生了什么,所以如果标题不具体,我深表歉意.我提供了下面的代码和 xaml 来演示我的问题.我有我调用的静态方法将位图转换为 byte [] ,反之亦然.当用于将源绑定到图像控件时,这些方法工作正常.但是,当我使用它们将源分配给作为 BlockUIContainer 子级的图像时,代码演示了......我在第二次调用 ByteArrayToBitmapSource 时得到了与前一个相同的图像.

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

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 主窗口.xaml

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>

推荐答案

我想这与返回一个 BitmapSource 作为对一个谨慎的 BitmapImage 的相反.创建此方法并改为调用此方法,它按我的预期工作.

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.

仍然不知道这是 FlowDocument 还是 XPSDocument 相关问题.

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;
}

这篇关于使用 PngBitmapDecoder、MemoryStream、FlowDocument、XPSDocument 预览图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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