我是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>
我相信我找到了解决问题的可能方案。
我确实必须先将条目转换为位图,然后使用流将其传输到位图图像。
图像现在显示出来。
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;
}
}
}