开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜