mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Support svg image file loading
This commit is contained in:
parent
f854cd3f76
commit
82f67884ef
4 changed files with 66 additions and 25 deletions
|
|
@ -67,6 +67,7 @@
|
|||
</PackageReference>
|
||||
<PackageReference Include="NLog" Version="4.7.10" />
|
||||
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0" />
|
||||
<PackageReference Include="SharpVectors.Wpf" Version="1.8.4.2" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||
<!--ToolGood.Words.Pinyin v3.0.2.6 results in high memory usage when search with pinyin is enabled-->
|
||||
<!--Bumping to it or higher needs to test and ensure this is no longer a problem-->
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ using System.Windows.Media;
|
|||
using System.Windows.Media.Imaging;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using Flow.Launcher.Infrastructure.Storage;
|
||||
using SharpVectors.Converters;
|
||||
using SharpVectors.Renderers.Wpf;
|
||||
|
||||
namespace Flow.Launcher.Infrastructure.Image
|
||||
{
|
||||
|
|
@ -25,8 +27,10 @@ namespace Flow.Launcher.Infrastructure.Image
|
|||
public static ImageSource LoadingImage { get; } = new BitmapImage(new Uri(Constant.LoadingImgIcon));
|
||||
public const int SmallIconSize = 64;
|
||||
public const int FullIconSize = 256;
|
||||
public const int FullImageSize = 320;
|
||||
|
||||
private static readonly string[] ImageExtensions = { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico" };
|
||||
private static readonly string SvgExtension = ".svg";
|
||||
|
||||
public static async Task InitializeAsync()
|
||||
{
|
||||
|
|
@ -245,6 +249,19 @@ namespace Flow.Launcher.Infrastructure.Image
|
|||
image = GetThumbnail(path, ThumbnailOptions.ThumbnailOnly);
|
||||
}
|
||||
}
|
||||
else if (extension == SvgExtension)
|
||||
{
|
||||
try
|
||||
{
|
||||
image = LoadFullSvgImage(path, loadFullImage);
|
||||
type = ImageType.FullImageFile;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
image = Image;
|
||||
type = ImageType.Error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
type = ImageType.File;
|
||||
|
|
@ -318,7 +335,7 @@ namespace Flow.Launcher.Infrastructure.Image
|
|||
return img;
|
||||
}
|
||||
|
||||
private static BitmapImage LoadFullImage(string path)
|
||||
private static ImageSource LoadFullImage(string path)
|
||||
{
|
||||
BitmapImage image = new BitmapImage();
|
||||
image.BeginInit();
|
||||
|
|
@ -327,24 +344,24 @@ namespace Flow.Launcher.Infrastructure.Image
|
|||
image.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
|
||||
image.EndInit();
|
||||
|
||||
if (image.PixelWidth > 320)
|
||||
if (image.PixelWidth > FullImageSize)
|
||||
{
|
||||
BitmapImage resizedWidth = new BitmapImage();
|
||||
resizedWidth.BeginInit();
|
||||
resizedWidth.CacheOption = BitmapCacheOption.OnLoad;
|
||||
resizedWidth.UriSource = new Uri(path);
|
||||
resizedWidth.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
|
||||
resizedWidth.DecodePixelWidth = 320;
|
||||
resizedWidth.DecodePixelWidth = FullImageSize;
|
||||
resizedWidth.EndInit();
|
||||
|
||||
if (resizedWidth.PixelHeight > 320)
|
||||
if (resizedWidth.PixelHeight > FullImageSize)
|
||||
{
|
||||
BitmapImage resizedHeight = new BitmapImage();
|
||||
resizedHeight.BeginInit();
|
||||
resizedHeight.CacheOption = BitmapCacheOption.OnLoad;
|
||||
resizedHeight.UriSource = new Uri(path);
|
||||
resizedHeight.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
|
||||
resizedHeight.DecodePixelHeight = 320;
|
||||
resizedHeight.DecodePixelHeight = FullImageSize;
|
||||
resizedHeight.EndInit();
|
||||
return resizedHeight;
|
||||
}
|
||||
|
|
@ -354,5 +371,44 @@ namespace Flow.Launcher.Infrastructure.Image
|
|||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static ImageSource LoadFullSvgImage(string path, bool loadFullImage = false)
|
||||
{
|
||||
// Set up drawing settings
|
||||
var desiredHeight = loadFullImage ? FullImageSize : SmallIconSize;
|
||||
var drawingSettings = new WpfDrawingSettings
|
||||
{
|
||||
IncludeRuntime = true,
|
||||
// Set IgnoreRootViewbox to false to respect the SVG's viewBox
|
||||
IgnoreRootViewbox = false
|
||||
};
|
||||
|
||||
// Load and render the SVG
|
||||
var converter = new FileSvgReader(drawingSettings);
|
||||
var drawing = converter.Read(path);
|
||||
|
||||
// Calculate scale to achieve desired height
|
||||
var drawingBounds = drawing.Bounds;
|
||||
var scale = desiredHeight / drawingBounds.Height;
|
||||
var scaledWidth = drawingBounds.Width * scale;
|
||||
var scaledHeight = drawingBounds.Height * scale;
|
||||
|
||||
// Convert the Drawing to a Bitmap
|
||||
var drawingVisual = new DrawingVisual();
|
||||
using DrawingContext drawingContext = drawingVisual.RenderOpen();
|
||||
drawingContext.PushTransform(new ScaleTransform(scale, scale));
|
||||
drawingContext.DrawDrawing(drawing);
|
||||
|
||||
// Create a RenderTargetBitmap to hold the rendered image
|
||||
var bitmap = new RenderTargetBitmap(
|
||||
(int)Math.Ceiling(scaledWidth),
|
||||
(int)Math.Ceiling(scaledHeight),
|
||||
96, // DpiX
|
||||
96, // DpiY
|
||||
PixelFormats.Pbgra32);
|
||||
bitmap.Render(drawingVisual);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,7 +438,9 @@ namespace Flow.Launcher.Plugin
|
|||
Task SaveCacheBinaryStorageAsync<T>(string cacheName, string cacheDirectory) where T : new();
|
||||
|
||||
/// <summary>
|
||||
/// Load image from path. Support local, remote and data:image url.
|
||||
/// Load image from path.
|
||||
/// Support local, remote and data:image url.
|
||||
/// Support png, jpg, jpeg, gif, bmp, tiff, ico, svg image files.
|
||||
/// If image path is missing, it will return a missing icon.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the image.</param>
|
||||
|
|
|
|||
|
|
@ -159,16 +159,7 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
|
|||
|
||||
if (!File.Exists(faviconPath))
|
||||
{
|
||||
// SVG 파일인지 확인
|
||||
if (IsSvgData(imageData))
|
||||
{
|
||||
bookmark.FaviconPath = defaultIconPath;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveBitmapData(imageData, faviconPath);
|
||||
}
|
||||
SaveBitmapData(imageData, faviconPath);
|
||||
}
|
||||
|
||||
bookmark.FaviconPath = faviconPath;
|
||||
|
|
@ -199,15 +190,6 @@ public abstract class FirefoxBookmarkLoaderBase : IBookmarkLoader
|
|||
}
|
||||
}
|
||||
|
||||
private static bool IsSvgData(byte[] data)
|
||||
{
|
||||
if (data.Length < 5)
|
||||
return false;
|
||||
string start = System.Text.Encoding.ASCII.GetString(data, 0, Math.Min(100, data.Length));
|
||||
return start.Contains("<svg") ||
|
||||
(start.StartsWith("<?xml") && start.Contains("<svg"));
|
||||
}
|
||||
|
||||
private static void SaveBitmapData(byte[] imageData, string outputPath)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
Loading…
Reference in a new issue