Как отобразить изображение из архива без распаковки архива - PullRequest
0 голосов
/ 04 февраля 2020

Я новичок с C# и WPF.

У меня есть архивный файл, например: Jonah Hex # 18.cbz. Этот архив содержит изображения (например: p0001.jpg, p0002.jpg и др. c.). Я пытаюсь отобразить эти изображения в приложении wpf без распаковки архива. Я использую библиотеку SharpCompress, чтобы прочитать архив, а затем загружаю метод, создающий BitmpapImage из имени этого изображения.

Я не могу получить изображения для отображения.

Я не уверен, нормально ли это или мне следует использовать StreamSource с потоком памяти вместо

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>

1 Ответ

0 голосов
/ 04 февраля 2020

Полагаю, я нашел возможное решение своей проблемы.

Мне нужно сначала преобразовать запись в растровое изображение, а затем использовать поток для его передачи в растровое изображение.

Изображение теперь отображается.

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


    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...