Scale down a Bitmap in WPF with best quality
How can I convert this GDI code to WPF code?
Icon bigIcon32x32 = null;
bigIcon32x32 = Icon.ExtractAssociatedIcon("c:\\test.docx");
Bitmap bm = bigIcon32x3开发者_JAVA百科2.ToBitmap();
Bitmap thumb16x16 = new Bitmap(16, 16);
Graphics graphics = Graphics.FromImage(thumb16x16);
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.DrawImage(bm, new Rectangle(0, 0, 16, 16), new Rectangle(0, 0, bm.Width, bm.Height), GraphicsUnit.Pixel);
graphics.Dispose();
bm.Dispose();
thumb16x16.Dispose();
It seems I have to use the ToBitmap() methode but from then on I want to use WPF only.
In the end I want to display small 16x16 pixel Images in a WPF DataGrid`s Column via Binding.
To show a bitmap in a DataGrid cell you can use a DataGridTemplateColumn with a DataTemplate using the IValueConverter to display an image in a DataGrid cell.
You can play with properties of BmpBitmapDecoder to achieve as good an image as possible.
Here is the definition for the DataGrid in XAML:
1- I have three columns in the DataGrid with the first one being the image.
2- I set Path=. because all I wanted to do was load the image from the converter.
3- The DataGrid binds to a Customers collection in a ViewModel, and I included the definitions of those for completeness at the end.
<Window x:Class="ContextMenuNotFiring.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Helpers="clr-namespace:ContextMenuNotFiring.Helpers"
Title="Main Window" Height="400" Width="800">
<Window.Resources>
<Helpers:ImageConverter x:Key="imgConv"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<DataGrid
Grid.Row="0"
IsSynchronizedWithCurrentItem="True"
Background="Transparent"
AutoGenerateColumns="False"
ItemsSource="{Binding Customers}">
<DataGrid.Columns>
<DataGridTemplateColumn
Header="Icon"
Width="SizeToHeader">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=., Converter={StaticResource imgConv}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Header="First Name"
Width="SizeToHeader"
Binding="{Binding FirstName}" />
<DataGridTextColumn
Header="Last Name"
Width="SizeToCells"
Binding="{Binding LastName}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Here is the converter that does a onetime lookup of the Word Doc's associated icon. If you want to handle multiple icons store the BitmapFrame references in a Dictionary and use the "value" input parameter to select which image to display.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;
namespace ContextMenuNotFiring.Helpers
{
[ValueConversion(typeof(object), typeof(BitmapSource))]
public sealed class ImageConverter : IValueConverter
{
private static BitmapFrame _bitmapFrame = null;
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
try
{
if (_bitmapFrame == null)
{
using (Icon bigIcon32x32 = Icon.ExtractAssociatedIcon("c:\\temp\\test.docx"))
{
using (Bitmap bm = bigIcon32x32.ToBitmap())
{
MemoryStream finalStream = new MemoryStream();
{
bm.Save(finalStream, ImageFormat.Bmp);
BmpBitmapDecoder bitmapDecoder = new BmpBitmapDecoder(finalStream,
BitmapCreateOptions.None, BitmapCacheOption.None);
_bitmapFrame = bitmapDecoder.Frames[0];
}
}
}
}
return _bitmapFrame;
}
catch
{
return Binding.DoNothing;
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
The View Model loads the following collection of Customers my View Model constructor.
private List<Customer> _customers = new List<Customer>():
public List<Customer> Customers
{
get
{
return _customers;
}
}
public class Customer
{
public String FirstName { get; set; }
public String LastName { get; set; }
}
精彩评论