mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[Peek] show thumbnail and fallback to icon on unsupported files (#27979)
This commit is contained in:
@@ -17,12 +17,23 @@ namespace Peek.FilePreviewer.Previewers.Helpers
|
||||
{
|
||||
public static async Task<BitmapSource> GetBitmapFromHBitmapAsync(IntPtr hbitmap, bool isSupportingTransparency, CancellationToken cancellationToken)
|
||||
{
|
||||
Bitmap? bitmap = null;
|
||||
|
||||
try
|
||||
{
|
||||
var bitmap = Image.FromHbitmap(hbitmap);
|
||||
if (isSupportingTransparency)
|
||||
bitmap = Image.FromHbitmap(hbitmap);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (isSupportingTransparency && bitmap.PixelFormat == PixelFormat.Format32bppRgb)
|
||||
{
|
||||
bitmap.MakeTransparent();
|
||||
var bitmapRectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
|
||||
var bitmapData = bitmap.LockBits(bitmapRectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
|
||||
var transparentBitmap = new Bitmap(bitmapData.Width, bitmapData.Height, bitmapData.Stride, PixelFormat.Format32bppArgb, bitmapData.Scan0);
|
||||
|
||||
bitmap.Dispose();
|
||||
bitmap = transparentBitmap;
|
||||
}
|
||||
|
||||
var bitmapImage = new BitmapImage();
|
||||
@@ -41,6 +52,8 @@ namespace Peek.FilePreviewer.Previewers.Helpers
|
||||
}
|
||||
finally
|
||||
{
|
||||
bitmap?.Dispose();
|
||||
|
||||
// delete HBitmap to avoid memory leaks
|
||||
NativeMethods.DeleteObject(hbitmap);
|
||||
}
|
||||
@@ -50,8 +63,8 @@ namespace Peek.FilePreviewer.Previewers.Helpers
|
||||
{
|
||||
try
|
||||
{
|
||||
var icon = (Icon)Icon.FromHandle(hicon).Clone();
|
||||
var bitmap = icon.ToBitmap();
|
||||
using var icon = (Icon)Icon.FromHandle(hicon).Clone();
|
||||
using var bitmap = icon.ToBitmap();
|
||||
|
||||
var bitmapImage = new BitmapImage();
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@ using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using Peek.Common;
|
||||
using Peek.Common.Extensions;
|
||||
using Peek.Common.Models;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers.Helpers
|
||||
@@ -20,6 +18,16 @@ namespace Peek.FilePreviewer.Previewers.Helpers
|
||||
private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
|
||||
|
||||
public static async Task<ImageSource?> GetIconAsync(string fileName, CancellationToken cancellationToken)
|
||||
{
|
||||
return await GetImageAsync(fileName, ThumbnailOptions.BiggerSizeOk | ThumbnailOptions.IconOnly, true, cancellationToken);
|
||||
}
|
||||
|
||||
public static async Task<ImageSource?> GetThumbnailAsync(string fileName, CancellationToken cancellationToken)
|
||||
{
|
||||
return await GetImageAsync(fileName, ThumbnailOptions.ThumbnailOnly, true, cancellationToken);
|
||||
}
|
||||
|
||||
public static async Task<ImageSource?> GetImageAsync(string fileName, ThumbnailOptions options, bool isSupportingTransparency, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
@@ -28,6 +36,7 @@ namespace Peek.FilePreviewer.Previewers.Helpers
|
||||
|
||||
ImageSource? imageSource = null;
|
||||
IShellItem? nativeShellItem = null;
|
||||
IntPtr hbitmap = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -40,16 +49,22 @@ namespace Peek.FilePreviewer.Previewers.Helpers
|
||||
}
|
||||
|
||||
NativeSize large = new NativeSize { Width = 256, Height = 256 };
|
||||
var options = ThumbnailOptions.BiggerSizeOk | ThumbnailOptions.IconOnly;
|
||||
|
||||
HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(large, options, out IntPtr hbitmap);
|
||||
HResult hr = ((IShellItemImageFactory)nativeShellItem).GetImage(large, options, out hbitmap);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
imageSource = hr == HResult.Ok ? await BitmapHelper.GetBitmapFromHBitmapAsync(hbitmap, true, cancellationToken) : null;
|
||||
imageSource = hr == HResult.Ok ? await BitmapHelper.GetBitmapFromHBitmapAsync(hbitmap, isSupportingTransparency, cancellationToken) : null;
|
||||
|
||||
hbitmap = IntPtr.Zero;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (hbitmap != IntPtr.Zero)
|
||||
{
|
||||
NativeMethods.DeleteObject(hbitmap);
|
||||
}
|
||||
|
||||
if (nativeShellItem != null)
|
||||
{
|
||||
Marshal.ReleaseComObject(nativeShellItem);
|
||||
|
||||
@@ -4,11 +4,9 @@
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using Peek.Common.Extensions;
|
||||
@@ -99,7 +97,8 @@ namespace Peek.FilePreviewer.Previewers
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var iconBitmap = await IconHelper.GetIconAsync(Item.Path, cancellationToken);
|
||||
var iconBitmap = await IconHelper.GetThumbnailAsync(Item.Path, cancellationToken)
|
||||
?? await IconHelper.GetIconAsync(Item.Path, cancellationToken);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user