如何在不提取档案的情况下从档案内部显示图像

问题描述 投票:0回答:1

我是C#和WPF的初学者。

我有一个存档文件,例如:Jonah Hex#18.cbz。该档案包含图像(例如:p0001.jpg,p0002.jpg等)。我正在尝试在wpf应用程序中显示这些图像而不提取存档。我正在使用SharpCompress库来读取存档,然后加载从该图像名称创建BitmpapImage的方法。

我无法显示图像。

我不确定这是否可以,或者我是否应该将StreamSource与memorystream一起使用,而不是

image.UriSource = new Uri(imageName, UriKind.RelativeOrAbsolute);

下面是我到目前为止的代码。我正在使用Prism,ViewModelBase继承自BindableBase,后者确实实现了InotifyPropertyChanged。

我将不胜感激。谢谢

using ComicSort.Core;
using ComicSort.UI.Models;
using Microsoft.Win32;
using Prism.Commands;
using Prism.Mvvm;
using SharpCompress.Archives;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;

namespace ComicSort.UI.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        #region Private Members

        private string _title = "ComicSort";


        #endregion

        #region Public Properties
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private ObservableCollection<BitmapImage> _thumbnail;
        public ObservableCollection<BitmapImage> Thumbnail
        {
            get { return _thumbnail; }
            set { SetProperty(ref _thumbnail, value); }
        }


        #endregion

        public MainWindowViewModel()
        {
            _thumbnail = new ObservableCollection<BitmapImage>();
        }

        private DelegateCommand _selectFileCommand;
        public DelegateCommand SelectFileCommand =>
            _selectFileCommand ?? (_selectFileCommand = new DelegateCommand(ExecuteSelectFileCommand));

        void ExecuteSelectFileCommand()
        {
            SelectFile();
        }

        private void SelectFile()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Filter = "CBZ files (*.cbz)|*.cbz|CBR files (*.cbr)|*.cbr|All Files (*.*)|*.*";
            Nullable<bool> result = openFileDialog.ShowDialog();

            if (result == true)
            {
                string filename = openFileDialog.FileName;
                OpenArchive(filename);
            }

        }

        private void OpenArchive(string filename)
        {
            string img = "";
            var archive = ArchiveFactory.Open(filename);
            foreach (IArchiveEntry entry in archive.Entries)
            {
                if (!entry.IsDirectory)
                {
                    if (entry.Key != "ComicInfo.xml")
                    {
                        img = entry.ToString();
                        LoadImages(img);
                    }

                }
            }

        }

        private BitmapImage LoadImages(string imageName)
        {
                BitmapImage image = new BitmapImage();
                image.BeginInit();
                image.UriSource = new Uri(imageName, UriKind.RelativeOrAbsolute);
                image.DecodePixelHeight = 128;
                image.CacheOption = BitmapCacheOption.OnDemand;
                image.EndInit();
                _thumbnail.Add(image);
                return image;
        }
    }
}

XAML现在相当简单

<Window x:Class="ComicSort.UI.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525" >

    <DockPanel LastChildFill="True">
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Header="_Select" Command="{Binding SelectFileCommand}"/>
            </MenuItem>
        </Menu>
        <Border DockPanel.Dock="Top">
            <WrapPanel>
                <Image Source="{Binding Thumbnail}"/>
            </WrapPanel>
        </Border>




    </DockPanel>
</Window>
c# wpf
1个回答
0
投票

我相信我找到了解决问题的可能方案。

我确实必须先将条目转换为位图,然后使用流将其传输到位图图像。

图像现在显示出来。

using ComicSort.Core;
using Microsoft.Win32;
using Prism.Commands;
using SharpCompress.Archives;
using System;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Media.Imaging;

namespace ComicSort.UI.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        #region Private Members

        private string _title = "ComicSort";


        #endregion

        #region Public Properties
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private ObservableCollection<BitmapImage> _thumbnail;
        public ObservableCollection<BitmapImage> Thumbnail
        {
            get { return _thumbnail; }
            set { SetProperty(ref _thumbnail, value); }
        }

        private BitmapImage _thumb;
        public BitmapImage Thumb
        {
            get { return _thumb; }
            set { SetProperty(ref _thumb, value); }
        }


        #endregion

        public MainWindowViewModel()
        {
            _thumbnail = new ObservableCollection<BitmapImage>();
        }

        private DelegateCommand _selectFileCommand;


        public DelegateCommand SelectFileCommand =>
            _selectFileCommand ?? (_selectFileCommand = new DelegateCommand(ExecuteSelectFileCommand));

        void ExecuteSelectFileCommand()
        {
            SelectFile();
        }

        private void SelectFile()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Filter = "CBZ files (*.cbz)|*.cbz|CBR files (*.cbr)|*.cbr|All Files (*.*)|*.*";
            Nullable<bool> result = openFileDialog.ShowDialog();

            if (result == true)
            {
                string filename = openFileDialog.FileName;
                OpenArchive(filename);

            }

        }



        private void OpenArchive(string filename)
        {

            var archive = ArchiveFactory.Open(filename);
            foreach (IArchiveEntry entry in archive.Entries)
            {
                if (!entry.IsDirectory)
                {
                    if (entry.Key != "ComicInfo.xml")
                    {

                        Bitmap bitmap = LoadImage(entry);
                        DisplayImage(bitmap);

                    }

                }
            }

        }

        private void DisplayImage(Bitmap bitmap)
        {
            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, ImageFormat.Jpeg);
            ms.Position = 0;
            BitmapImage image = new BitmapImage();


            image.BeginInit();
            image.StreamSource = ms;
            image.DecodePixelHeight = 128;
            image.CacheOption = BitmapCacheOption.OnDemand;
            image.EndInit();

            Thumb = image;

            }

        private Bitmap LoadImage(IArchiveEntry fileEntry)
        {

            Bitmap bitmap = (Bitmap)Bitmap.FromStream(fileEntry.OpenEntryStream());
            return bitmap;
        }


    }
}
© www.soinside.com 2019 - 2024. All rights reserved.