首页 / C# / 使用C#/ WPF显示缩略图网格
使用C#/ WPF显示缩略图网格
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用C#/ WPF显示缩略图网格,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4069字,纯文字阅读大概需要6分钟。
内容图文
![使用C#/ WPF显示缩略图网格](/upload/InfoBanner/zyjiaocheng/679/2a2edae293084b90b3506db458507da2.jpg)
在我的C#/ WPF应用程序中,我想显示图像文件目录树中的图像缩略图网格(当前为.bmp,但最终为其他格式).将来,我可能希望允许用户单击缩略图以查看较大的版本,或者将鼠标悬停在该缩略图上以查看一些技术细节,但是现在我要做的就是显示缩略图.
图像的数量是不可预测的,我的指示是如果屏幕上容纳的图像数量超出我的承受能力,则应启用滚动功能(而不是缩小缩略图).
我有一个递归例程,可以遍历树并标识要显示的文件. . .
private bool WalkTree(String sRoot)
{
string sDirectoryName;
string sFileName;
int iDirectoryCount = 0;
DirectoryInfo DirInfo;
DirInfo = new DirectoryInfo(sRoot);
// Get a list of all the files in this directory.
foreach (FileInfo fi in DirInfo.GetFiles("*.bmp"))
{
sFileName = fi.Name;
// DO SOMETHING WITH FILE FOUND HERE
}
// Now get a list of all the subfolders in this directory.
foreach (DirectoryInfo di in DirInfo.GetDirectories())
{
sDirectoryName = di.Name;
WalkTree(sRoot + "\\" + sDirectoryName); //recurse!!
iDirectoryCount++;
}
return true;
} // End WalkTree
那么执行此操作的好方法是什么?我应该使用哪种XAML控件来放入所有这些控件?网格?我可以在其中添加行并使它在递归并发现更多文件时滚动吗?还是我应该走两次树-一次计数并配置页面中的行和列,第二次实际显示缩略图?还是我在想这一切错了?
我觉得这个问题在过去一定已经解决了很多次,必须有一个规范的设计模式,但是我找不到.
解决方法:
注释描述了如何进行布局部分.这相对容易,使用哪种解决方案取决于实际的布局. UniformGrid很好.在这里使用ItemsControl就足够了:
<ItemsControl ItemsSource="{Binding Images}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<ScrollViewer>
<UniformGrid />
</ScrollViewer>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Width="100" Height="100" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
问题是:什么是图像,将ItemsSource绑定到的属性?您所拥有的是带有文件名的字符串列表,您需要的是一系列ImageSources.无法将图像加载到内存中.如果您不希望在图像数量众多且很大时,您的应用程序不占用大量内存,则仍然需要有效地执行此操作.一个选项是将图像缩放为缩略图.其次,在缩放图像时,这也是裁剪图像以及获得固定长宽比并使网格看起来不错的好机会.
为了与Image控件的ImageSource属性绑定,图像在这里需要是BitmapImage的集合.
public ObservableCollection<BitmapImage> Images { get; set; }
这基本上就是//在这里找到文件的地方:
var image = CreateBitmap(path);
var width = image.PixelWidth;
var height = image.PixelHeight;
// Crop image (cut the side which is too long)
var expectedHeightAtCurrentWidth = width*4.0/3.0;
var expectedWidthAtCurrentHeight = height*3.0/4.0;
var newWidth = Math.Min(expectedWidthAtCurrentHeight, width);
var newHeight = Math.Min(expectedHeightAtCurrentWidth, height);
var croppedImage = CropImage(image, (int)newWidth, (int)newHeight);
// Scale to with of 100px
var ratio= 100.0 / newWidth;
var scaledImage = ScaleImage(croppedImage, ratio);
Images.Add(scaledImage);
使用以下功能来创建,缩放和裁剪图像:
private static BitmapImage CreateBitmap(string path)
{
var bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(path);
bi.EndInit();
return bi;
}
private BitmapImage ScaleImage(BitmapImage original, double scale)
{
var scaledBitmapSource = new TransformedBitmap();
scaledBitmapSource.BeginInit();
scaledBitmapSource.Source = original;
scaledBitmapSource.Transform = new ScaleTransform(scale, scale);
scaledBitmapSource.EndInit();
return BitmapSourceToBitmap(scaledBitmapSource);
}
private BitmapImage CropImage(BitmapImage original, int width, int height)
{
var deltaWidth = original.PixelWidth - width;
var deltaHeight = original.PixelHeight - height;
var marginX = deltaWidth/2;
var marginY = deltaHeight/2;
var rectangle = new Int32Rect(marginX, marginY, width, height);
var croppedBitmap = new CroppedBitmap(original, rectangle);
return BitmapSourceToBitmap(croppedBitmap);
}
private BitmapImage BitmapSourceToBitmap(BitmapSource source)
{
var encoder = new PngBitmapEncoder();
var memoryStream = new MemoryStream();
var image = new BitmapImage();
encoder.Frames.Add(BitmapFrame.Create(source));
encoder.Save(memoryStream);
image.BeginInit();
image.StreamSource = new MemoryStream(memoryStream.ToArray());
image.EndInit();
memoryStream.Close();
return image;
}
内容总结
以上是互联网集市为您收集整理的使用C#/ WPF显示缩略图网格全部内容,希望文章能够帮你解决使用C#/ WPF显示缩略图网格所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。