I found a reasonably priced product ($600) that will create an image of a pdf page and has a free demo version. The product is called Spire.pdf. Other products such as ExpertPdf and ActivePdf don't appear to offer this feature.
Creating a thumbnail from an image file is trivial and requires no special downloads.
I also wanted to leverage the Shell dll to display application icons for the other file types.
Start a new WPF project called FileThumbnails. I'm using Visual Studio 2019, C#, and targeting Framework 4.7.
Start by adding the Spire demo product using NuGet. Browse to Tools -> NuGet Package Manager -> Manage NugetPackages for Solution. Click Browse and search for Spire.pdf. Install FreeSpire.pdf.
Now we need to install the windows api code pack. Select Browse and search for microsoft.windowsapicodepack.shell. Pick the one from Microsoft and install it into the project.
Now add a reference to System.Drawing.
The application will list three files (substitute your own). Each one will have a tooltip which is either a thumbnail of the first page of the file or the icon of the owning application.
Here's the XAML.
<Window x:Class="FileThumbnails.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FileThumbnails"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding pdfFileName}">
<TextBlock.ToolTip>
<Image Source="{Binding pdfTooltip}" Stretch="Uniform" Width="200"/>
</TextBlock.ToolTip>
</TextBlock>
<TextBlock Text="{Binding imgFileName}">
<TextBlock.ToolTip>
<Image Source="{Binding imgTooltip}" Stretch="Uniform" Width="200"/>
</TextBlock.ToolTip>
</TextBlock>
<TextBlock Text="{Binding otherFileName}">
<TextBlock.ToolTip>
<Image Source="{Binding otherTooltip}" Stretch="Uniform" Width="200"/>
</TextBlock.ToolTip>
</TextBlock>
</StackPanel>
</Window>
Here's the code-behind. We'll complete the interesting bits later.
using System;
using System.Windows;
using System.Windows.Media.Imaging;
using Microsoft.WindowsAPICodePack.Shell;
using System.Drawing;
using Spire.Pdf;
using System.IO;
using System.Drawing.Imaging;
using System.ComponentModel;
namespace FileThumbnails
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public String pdfFileName { get; set; }
public BitmapImage pdfTooltip
{
get { return
GetToolTip(pdfFileName); }
}
public String imgFileName { get; set; }
public BitmapImage imgTooltip
{
get
{
return GetToolTip(imgFileName);
}
}
public String otherFileName { get; set; }
public BitmapImage otherTooltip
{
get
{
return GetToolTip(otherFileName);
}
}
public MainWindow()
{
pdfFileName = @"C:\Users\me\documents\Expectations.pdf";
imgFileName = @"C:\Users\me\documents\20190421.jpg";
otherFileName = @"C:\Users\me\documents\ELTS.docx";
InitializeComponent();
}
public BitmapImage GetToolTip(String FileName)
{
String Extension =
System.IO.Path.GetExtension(FileName).ToUpper();
switch (Extension)
{
case ".PDF": return
GetPDFThumbnail(FileName);
case ".PNG":
case ".BMP":
case ".JPG": return
GetImageThumbnail(FileName);
default: return
GetApplicationIcon(FileName);
}
}
private BitmapImage GetPDFThumbnail(String FileName)
{
}
private BitmapImage GetImageThumbnail(String FileName)
{
}
private BitmapImage GetApplicationIcon(String FileName)
{
}
public event
PropertyChangedEventHandler PropertyChanged;
public void
PropChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
private BitmapImage GetPDFThumbnail(String FileName)
{
PdfDocument doc = new PdfDocument();
doc.LoadFromFile(pdfFileName);
Bitmap bmp =
(Bitmap)doc.SaveAsImage(0);
using (MemoryStream ms = new MemoryStream())
{
bmp.Save(ms, ImageFormat.Png);
ms.Position = 0;
BitmapImage bmi = new BitmapImage();
bmi.BeginInit();
bmi.StreamSource = ms;
bmi.CacheOption = BitmapCacheOption.OnLoad;
bmi.EndInit();
return bmi;
}
}
Now the image, which is trivial.
private BitmapImage GetImageThumbnail(String FileName)
{
BitmapImage bmi = new BitmapImage();
bmi.BeginInit();
bmi.UriSource = new Uri(FileName);
bmi.DecodePixelWidth = 200;
bmi.EndInit();
return bmi;
}
The only interesting thing here is bmi.DecodePixelWidth = 200 which speeds up the resizing.
The last method we need to complete fetches the icon of the owner of the specified file type and converts that to a BitmapImage. Again - the bulk of the code is involved with converting from one type of image to another.
private BitmapImage GetApplicationIcon(String FileName)
{
BitmapSource bms =
ShellFile.FromFilePath(FileName).Thumbnail.BitmapSource;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
MemoryStream ms = new MemoryStream();
BitmapImage bmi = new BitmapImage();
encoder.Frames.Add(BitmapFrame.Create(bms));
encoder.Save(ms);
ms.Position = 0;
bmi.BeginInit();
bmi.StreamSource = new MemoryStream(ms.ToArray());
bmi.EndInit();
return bmi;
}
Here are the results.
Image tool tip |
Other tool tip |
Pdf tool tip |
No comments:
Post a Comment