-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPlugin.cs
144 lines (128 loc) · 5.14 KB
/
Plugin.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.IO;
using System.Linq;
using QuickLook.Common.Plugin;
using QuickLook.Plugin.ImageViewer;
using System.Text;
using QuickLook.Common.Helpers;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace QuickLook.Plugin.DDSViewer
{
public class Plugin : IViewer
{
private string _imagePath;
private ImagePanel _ip;
private MetaProvider _meta;
private Pfim.IImage _image;
private PixelFormat format;
public int Priority => 0;
public void Init()
{
}
public bool CanHandle(string path)
{
return !Directory.Exists(path) && new[] { ".dds" }.Any(path.ToLower().EndsWith);
}
public void Prepare(string path, ContextObject context)
{
_imagePath = ExtractFile(path);
_meta = new MetaProvider(_imagePath);
var size = _meta.GetSize();
if (!size.IsEmpty)
context.SetPreferredSizeFit(size, 0.8);
else
context.PreferredSize = new System.Windows.Size(800, 600);
context.Theme = (Themes)SettingHelper.Get("LastTheme", 1, "QuickLook.Plugin.ImageViewer");
}
public void View(string path, ContextObject context)
{
_imagePath = ExtractFile(path);
_ip = new ImagePanel();
_ip.ContextObject = context;
_ip.Meta = _meta;
_ip.Theme = context.Theme;
var size = _meta.GetSize();
context.ViewerContent = _ip;
context.Title = size.IsEmpty
? $"{Path.GetFileName(path)}"
: $"{size.Width}×{size.Height}: {Path.GetFileName(path)}";
_ip.ImageUriSource = FilePathToFileUrl(_imagePath);
}
public void Cleanup()
{
_ip?.Dispose();
_ip = null;
}
private string ExtractFile(string path)
{
string curAssemblyFolder = new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath;
curAssemblyFolder = Path.GetDirectoryName(curAssemblyFolder);
string destinationPath = Path.GetFullPath(Path.Combine(curAssemblyFolder, "thumbnail.png"));
_image = Pfim.Pfim.FromFile(path);
if (_image.Compressed)
{
_image.Decompress();
}
switch (_image.Format)
{
// /~https://github.com/nickbabcock/Pfim/blob/master/src/Pfim.Skia/Program.cs
case Pfim.ImageFormat.Rgba32:
format = PixelFormat.Format32bppArgb;
//Image.LoadPixelData<Bgra32>(_image.Data, _image.Width, _image.Height).Save(destinationPath);
break;
case Pfim.ImageFormat.Rgb24:
format = PixelFormat.Format24bppRgb;
//Image.LoadPixelData<Bgr24>(_image.Data, _image.Width, _image.Height).Save(destinationPath);
break;
case Pfim.ImageFormat.R5g5b5a1:
format = PixelFormat.Format16bppArgb1555;
break;
case Pfim.ImageFormat.Rgb8:
format = PixelFormat.Format8bppIndexed;
break;
case Pfim.ImageFormat.R5g6b5:
format = PixelFormat.Format16bppRgb565;
break;
case Pfim.ImageFormat.R5g5b5:
format = PixelFormat.Format16bppRgb555;
break;
case Pfim.ImageFormat.Rgba16:
throw new Exception("Unsupported pixel format (" + _image.Format + ")");
default:
//Log.Logger.Warning("Image {inputPath} had unknown format {format}", path, _image.Format);
throw new Exception("Unsupported pixel format (" + _image.Format + ")");
}
var data = Marshal.UnsafeAddrOfPinnedArrayElement(_image.Data, 0);
var bitmap = new Bitmap(_image.Width, _image.Height, _image.Stride, format, data);
bitmap.Save(destinationPath, ImageFormat.Png);
return destinationPath;
}
public Uri FilePathToFileUrl(string filePath)
{
var uri = new StringBuilder();
foreach (var v in filePath)
if (v >= 'a' && v <= 'z' || v >= 'A' && v <= 'Z' || v >= '0' && v <= '9' ||
v == '+' || v == '/' || v == ':' || v == '.' || v == '-' || v == '_' || v == '~' ||
v > '\x80')
uri.Append(v);
else if (v == Path.DirectorySeparatorChar || v == Path.AltDirectorySeparatorChar)
uri.Append('/');
else
uri.Append($"%{(int)v:X2}");
if (uri.Length >= 2 && uri[0] == '/' && uri[1] == '/') // UNC path
uri.Insert(0, "file:");
else
uri.Insert(0, "file:///");
try
{
return new Uri(uri.ToString());
}
catch
{
return new Uri(filePath);
}
}
}
}