Swirth to ImageMagick which supports PSD and RAW images

This commit is contained in:
Paddy Xu
2017-06-02 19:01:45 +03:00
parent 903c90472b
commit 96a46e3a23
6 changed files with 90 additions and 77 deletions

View File

@@ -1,53 +1,48 @@
using System.IO; using System;
using System.Windows; using System.Windows;
using System.Windows.Media.Imaging; using ExifLib;
using ImageMagick;
namespace QuickLook.Plugin.ImageViewer namespace QuickLook.Plugin.ImageViewer
{ {
internal static class ImageFileHelper internal static class ImageFileHelper
{ {
internal static Size GetImageSize(string path) internal static Size? GetImageSize(string path)
{ {
var ori = GetOrientationFromExif(path); var ori = GetOrientationFromExif(path);
using (var stream = File.OpenRead(path)) try
{ {
var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.None); var info = new MagickImageInfo(path);
var frame = decoder.Frames[0];
if (ori == ExifOrientation.Rotate90CW || ori == ExifOrientation.Rotate270CW) if (ori == OrientationType.RightTop || ori == OrientationType.LeftBotom)
return new Size {Width = frame.PixelHeight, Height = frame.PixelWidth}; return new Size {Width = info.Height, Height = info.Width};
return new Size {Width = info.Width, Height = info.Height};
return new Size {Width = frame.PixelWidth, Height = frame.PixelHeight}; }
catch (MagickException)
{
return null;
} }
} }
internal static ExifOrientation GetOrientationFromExif(string path) private static OrientationType GetOrientationFromExif(string path)
{ {
using (var stream = File.OpenRead(path)) try
{ {
var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.None); using (var re = new ExifReader(path))
var frame = decoder.Frames[0]; {
re.GetTagValue(ExifTags.Orientation, out ushort orientation);
var orientation = ((BitmapMetadata) frame.Metadata)?.GetQuery(@"/app1/{ushort=0}/{ushort=274}"); if (orientation == 0)
return OrientationType.Undefined;
if (orientation == null) return (OrientationType) orientation;
return ExifOrientation.Horizontal; }
}
return (ExifOrientation) (ushort) orientation; catch (Exception)
{
return OrientationType.Undefined;
} }
}
internal enum ExifOrientation
{
Horizontal = 1,
MirrorHorizontal = 2,
Rotate180 = 3,
MirrorVertical = 4,
MirrorHorizontal270CW = 5,
Rotate90CW = 6,
MirrorHorizontal90CW = 7,
Rotate270CW = 8
} }
} }
} }

View File

@@ -4,7 +4,7 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using ImageMagick;
using XamlAnimatedGif; using XamlAnimatedGif;
namespace QuickLook.Plugin.ImageViewer namespace QuickLook.Plugin.ImageViewer
@@ -30,37 +30,28 @@ namespace QuickLook.Plugin.ImageViewer
viewPanel.PreviewMouseLeftButtonDown += ViewPanel_PreviewMouseLeftButtonDown; viewPanel.PreviewMouseLeftButtonDown += ViewPanel_PreviewMouseLeftButtonDown;
viewPanel.PreviewMouseMove += ViewPanel_PreviewMouseMove; viewPanel.PreviewMouseMove += ViewPanel_PreviewMouseMove;
viewPanel.TouchDown += ViewPanel_TouchDown;
}
private void ViewPanel_TouchDown(object sender, TouchEventArgs e)
{
// TODO: touch support
} }
private void LoadImage(string path) private void LoadImage(string path)
{ {
var ori = ImageFileHelper.GetOrientationFromExif(path); if (Path.GetExtension(path).ToLower() == ".gif")
var bitmap = new BitmapImage();
using (var fs = File.OpenRead(path))
{ {
bitmap.BeginInit(); AnimationBehavior.SetSourceUri(viewPanelImage, new Uri(path));
bitmap.StreamSource = fs; return;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.Rotation = ori == ImageFileHelper.ExifOrientation.Rotate90CW
? Rotation.Rotate90
: ori == ImageFileHelper.ExifOrientation.Rotate270CW
? Rotation.Rotate270
: Rotation.Rotate0;
bitmap.EndInit();
} }
viewPanelImage.Source = bitmap; using (var image = new MagickImage(path))
{
image.Rotate(image.Orientation == OrientationType.RightTop
? 90
: image.Orientation == OrientationType.BottomRight
? 180
: image.Orientation == OrientationType.LeftBotom
? 270
: 0);
if (Path.GetExtension(path).ToLower() == ".gif") viewPanelImage.Source = image.ToBitmapSource();
AnimationBehavior.SetSourceUri(viewPanelImage, new Uri(path)); }
} }
private void ViewPanel_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) private void ViewPanel_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

View File

@@ -1,10 +1,22 @@
using System.IO; using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows; using System.Windows;
namespace QuickLook.Plugin.ImageViewer namespace QuickLook.Plugin.ImageViewer
{ {
public class Plugin : IViewer public class Plugin : IViewer
{ {
private static readonly string[] _formats =
{
// camera raw
".3fr", ".ari", ".arw", ".bay", ".crw", ".cr2", ".cap", ".data", ".dcs", ".dcr", ".dng", ".drf", ".eip",
".erf", ".fff", ".gpr", ".iiq", ".k25", ".kdc", ".mdc", ".mef", ".mos", ".mrw", ".nef", ".nrw", ".obm",
".orf", ".pef", ".ptx", ".pxn", ".r3d", ".raf", ".raw", ".rwl", ".rw2", ".rwz", ".sr2", ".srf", ".srw",
".tif", ".x3f",
// normal
".bmp", ".gif", ".ico", ".jpg", ".jpeg", ".png", ".psd", ".svg", ".wdp", ".tiff", ".tga"
};
private Size _imageSize; private Size _imageSize;
private ImagePanel _ip; private ImagePanel _ip;
@@ -13,47 +25,39 @@ namespace QuickLook.Plugin.ImageViewer
public bool CanHandle(string path) public bool CanHandle(string path)
{ {
// TODO: determine file type by content
if (Directory.Exists(path)) if (Directory.Exists(path))
return false; return false;
switch (Path.GetExtension(path).ToLower()) return _formats.Contains(Path.GetExtension(path).ToLower());
{
case ".bmp":
case ".gif":
case ".ico":
case ".jpg":
case ".jpeg":
case ".png":
case ".wdp":
case ".tiff":
return true;
default:
return false;
}
} }
public void Prepare(string path, ContextObject context) public void Prepare(string path, ContextObject context)
{ {
_imageSize = ImageFileHelper.GetImageSize(path); // ImageMagick want to have dcraw.exe
Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
context.SetPreferredSizeFit(_imageSize, 0.8); _imageSize = ImageFileHelper.GetImageSize(path) ?? Size.Empty;
if (!_imageSize.IsEmpty)
context.SetPreferredSizeFit(_imageSize, 0.8);
else
context.PreferredSize = new Size(1024, 768);
} }
public void View(string path, ContextObject context) public void View(string path, ContextObject context)
{ {
_ip = new ImagePanel(path); _ip = new ImagePanel(path);
context.ViewerContent = _ip; context.ViewerContent = _ip;
context.Title = $"{Path.GetFileName(path)} ({_imageSize.Width}×{_imageSize.Height})"; context.Title = _imageSize.IsEmpty
? $"{Path.GetFileName(path)}"
: $"{Path.GetFileName(path)} ({_imageSize.Width}×{_imageSize.Height})";
context.IsBusy = false; context.IsBusy = false;
} }
public void Cleanup() public void Cleanup()
{ {
Directory.SetCurrentDirectory(App.AppPath);
_ip = null; _ip = null;
} }
} }

View File

@@ -12,6 +12,8 @@
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -32,10 +34,17 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="ExifLib, Version=1.7.0.0, Culture=neutral, PublicKeyToken=30284005913968db, processorArchitecture=MSIL">
<HintPath>..\..\packages\ExifLib.1.7.0.0\lib\net45\ExifLib.dll</HintPath>
</Reference>
<Reference Include="Magick.NET-Q8-x86, Version=7.0.0.0, Culture=neutral, PublicKeyToken=2004825badfa91ec, processorArchitecture=x86">
<HintPath>..\..\packages\Magick.NET-Q8-x86.7.0.5.900\lib\net40-client\Magick.NET-Q8-x86.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xaml" /> <Reference Include="System.Xaml" />
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
<Reference Include="XamlAnimatedGif, Version=1.1.9.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="XamlAnimatedGif, Version=1.1.9.0, Culture=neutral, processorArchitecture=MSIL">
@@ -69,5 +78,17 @@
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="dcraw.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\packages\Magick.NET-Q8-x86.7.0.5.900\build\net40-client\Magick.NET-Q8-x86.targets" Condition="Exists('..\..\packages\Magick.NET-Q8-x86.7.0.5.900\build\net40-client\Magick.NET-Q8-x86.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Magick.NET-Q8-x86.7.0.5.900\build\net40-client\Magick.NET-Q8-x86.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Magick.NET-Q8-x86.7.0.5.900\build\net40-client\Magick.NET-Q8-x86.targets'))" />
</Target>
</Project> </Project>

View File

@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="XamlAnimatedGif" version="1.1.9" targetFramework="net452" /> <package id="ExifLib" version="1.7.0.0" targetFramework="net462" />
<package id="Magick.NET-Q8-x86" version="7.0.5.900" targetFramework="net462" />
<package id="XamlAnimatedGif" version="1.1.9" targetFramework="net462" />
</packages> </packages>