Skip to content

Commit

Permalink
[Peek] show thumbnail and fallback to icon on unsupported files (#27979)
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrolamas authored Aug 24, 2023
1 parent efee03e commit c1316fc
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,23 @@ public static class BitmapHelper
{
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();
Expand All @@ -41,6 +52,8 @@ public static async Task<BitmapSource> GetBitmapFromHBitmapAsync(IntPtr hbitmap,
}
finally
{
bitmap?.Dispose();

// delete HBitmap to avoid memory leaks
NativeMethods.DeleteObject(hbitmap);
}
Expand All @@ -50,8 +63,8 @@ public static async Task<BitmapSource> GetBitmapFromHIconAsync(IntPtr hicon, Can
{
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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
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
Expand All @@ -20,6 +18,16 @@ public static class IconHelper
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))
{
Expand All @@ -28,6 +36,7 @@ public static class IconHelper

ImageSource? imageSource = null;
IShellItem? nativeShellItem = null;
IntPtr hbitmap = IntPtr.Zero;

try
{
Expand All @@ -40,16 +49,22 @@ public static class IconHelper
}

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -76,7 +74,7 @@ public async Task LoadPreviewAsync(CancellationToken cancellationToken)
else
{
State = PreviewState.Loaded;
}
}
}

public async Task CopyAsync()
Expand All @@ -99,7 +97,8 @@ await Dispatcher.RunOnUiThread(async () =>
{
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();

Expand Down

0 comments on commit c1316fc

Please sign in to comment.