在WPF中缩小位图以获得最佳质量

时间:2011-03-11 23:41:38

标签: wpf image bitmap scale

如何将此GDI代码转换为WPF代码?

Icon bigIcon32x32 = null;
                    bigIcon32x32 = Icon.ExtractAssociatedIcon("c:\\test.docx");                    

                    Bitmap bm = bigIcon32x32.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(); 

似乎我必须使用ToBitmap()方法,但从那时起我只想使用WPF。

最后,我想通过Binding在WPF DataGrid的列中显示小的16x16像素图像。

1 个答案:

答案 0 :(得分:1)

要在DataGrid单元格中显示位图,您可以使用DataGridTemplateColumn和DataTemplate,使用IValueConverter在DataGrid单元格中显示图像。

您可以使用BmpBitmapDecoder的属性来实现尽可能好的图像。

以下是XAML中DataGrid的定义:
1-我在DataGrid中有三列,第一列是图像 2-我设置Path =。因为我想做的就是从转换器加载图像 3- DataGrid绑定到ViewModel中的Customers集合,最后我在其中包含了完整性的定义。

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

这是转换器,可以一次性查找Word Doc的相关图标。 如果要处理多个图标,请在Dictionary中存储BitmapFrame引用,并使用“value”输入参数选择要显示的图像。

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

视图模型加载以下客户集合我的视图模型构造函数。

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