diff --git a/src/Files.App/Data/Enums/IconOptions.cs b/src/Files.App/Data/Enums/IconOptions.cs
index 0f4298637668..32b9627a34e7 100644
--- a/src/Files.App/Data/Enums/IconOptions.cs
+++ b/src/Files.App/Data/Enums/IconOptions.cs
@@ -19,19 +19,24 @@ public enum IconOptions
 		/// </summary>
 		UseCurrentScale = 1,
 
+		/// <summary>
+		/// Scale the thumbnail to the requested size.
+		/// </summary>
+		ResizeThumbnail = 2,
+
 		/// <summary>
 		/// Retrieve only the file icon, even a thumbnail is available. This has the best performance.
 		/// </summary>
-		ReturnIconOnly = 2,
+		ReturnIconOnly = 4,
 
 		/// <summary>
 		/// Retrieve only the thumbnail.
 		/// </summary>
-		ReturnThumbnailOnly = 4,
+		ReturnThumbnailOnly = 8,
 
 		/// <summary>
 		/// Retrieve a thumbnail only if it is cached or embedded in the file.
 		/// </summary>
-		ReturnOnlyIfCached = 8,
+		ReturnOnlyIfCached = 16,
 	}
 }
diff --git a/src/Files.App/Data/Items/DriveItem.cs b/src/Files.App/Data/Items/DriveItem.cs
index 6c72c3769c41..0d9086d1b8d9 100644
--- a/src/Files.App/Data/Items/DriveItem.cs
+++ b/src/Files.App/Data/Items/DriveItem.cs
@@ -6,15 +6,15 @@
 using Microsoft.UI.Xaml.Controls;
 using Microsoft.UI.Xaml.Media.Imaging;
 using Windows.Storage;
-using Windows.Storage.Streams;
+using Windows.Storage.FileProperties;
 using ByteSize = ByteSizeLib.ByteSize;
 
 namespace Files.App.Data.Items
 {
 	public sealed class DriveItem : ObservableObject, INavigationControlItem, ILocatableFolder
 	{
-		private BitmapImage icon;
-		public BitmapImage Icon
+		private BitmapImage? icon;
+		public BitmapImage? Icon
 		{
 			get => icon;
 			set
@@ -24,7 +24,7 @@ public BitmapImage Icon
 			}
 		}
 
-		public byte[] IconData { get; set; }
+		public byte[]? IconData { get; set; }
 
 		private string path;
 		public string Path
@@ -232,12 +232,11 @@ private void ItemDecorator_Click(object sender, RoutedEventArgs e)
 			DriveHelpers.EjectDeviceAsync(Path);
 		}
 
-		public static async Task<DriveItem> CreateFromPropertiesAsync(StorageFolder root, string deviceId, string label, DriveType type, IRandomAccessStream imageStream = null)
+		public static async Task<DriveItem> CreateFromPropertiesAsync(StorageFolder root, string deviceId, string label, DriveType type, byte[]? imageData = null)
 		{
 			var item = new DriveItem();
 
-			if (imageStream is not null)
-				item.IconData = await imageStream.ToByteArrayAsync();
+			item.IconData = imageData;
 
 			item.Text = type switch
 			{
@@ -336,8 +335,7 @@ public async Task LoadThumbnailAsync()
 
 			if (Root is not null)
 			{
-				using var thumbnail = await DriveHelpers.GetThumbnailAsync(Root);
-				IconData ??= thumbnail is not null ? await thumbnail.ToByteArrayAsync() : null;
+				IconData ??= await FileThumbnailHelper.GetIconAsync(Root, 40, ThumbnailMode.SingleItem, ThumbnailOptions.UseCurrentScale);
 			}
 
 			if (string.Equals(DeviceID, "network-folder"))
diff --git a/src/Files.App/Data/Items/WidgetDriveCardItem.cs b/src/Files.App/Data/Items/WidgetDriveCardItem.cs
index 08e3d1136831..06efcae63910 100644
--- a/src/Files.App/Data/Items/WidgetDriveCardItem.cs
+++ b/src/Files.App/Data/Items/WidgetDriveCardItem.cs
@@ -2,6 +2,7 @@
 // Licensed under the MIT License.
 
 using Microsoft.UI.Xaml.Media.Imaging;
+using Windows.Storage.FileProperties;
 
 namespace Files.App.Data.Items
 {
@@ -34,8 +35,7 @@ public async Task LoadCardThumbnailAsync()
 
 			if (result is null)
 			{
-				using var thumbnail = await DriveHelpers.GetThumbnailAsync(Item.Root);
-				result ??= await thumbnail.ToByteArrayAsync();
+				result ??= await FileThumbnailHelper.GetIconAsync(Item.Root, 40, ThumbnailMode.SingleItem, ThumbnailOptions.UseCurrentScale);
 			}
 
 			thumbnailData = result;
diff --git a/src/Files.App/Data/Models/PinnedFoldersManager.cs b/src/Files.App/Data/Models/PinnedFoldersManager.cs
index d2e84d1cd57a..4fb9036342e8 100644
--- a/src/Files.App/Data/Models/PinnedFoldersManager.cs
+++ b/src/Files.App/Data/Models/PinnedFoldersManager.cs
@@ -108,6 +108,7 @@ public async Task<LocationItem> CreateLocationItemFromPathAsync(string path)
 				{
 					var result = await FileThumbnailHelper.GetIconAsync(
 						res.Result.Path,
+						res.Result,
 						Constants.ShellIconSizes.Small,
 						true,
 						IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
diff --git a/src/Files.App/Services/Storage/StorageDevicesService.cs b/src/Files.App/Services/Storage/StorageDevicesService.cs
index a13ab8d41a42..a336853c05a9 100644
--- a/src/Files.App/Services/Storage/StorageDevicesService.cs
+++ b/src/Files.App/Services/Storage/StorageDevicesService.cs
@@ -6,6 +6,7 @@
 using Microsoft.Extensions.Logging;
 using System.IO;
 using Windows.Storage;
+using Windows.Storage.FileProperties;
 
 namespace Files.App.Services
 {
@@ -42,7 +43,7 @@ public async IAsyncEnumerable<ILocatableFolder> GetDrivesAsync()
 					continue;
 				}
 
-				using var thumbnail = await DriveHelpers.GetThumbnailAsync(res.Result);
+				var thumbnail = await FileThumbnailHelper.GetIconAsync(res.Result, 40, ThumbnailMode.SingleItem, ThumbnailOptions.UseCurrentScale);
 				var type = DriveHelpers.GetDriveType(drive);
 				var label = DriveHelpers.GetExtendedDriveLabel(drive);
 				var driveItem = await DriveItem.CreateFromPropertiesAsync(res.Result, drive.Name.TrimEnd('\\'), label, type, thumbnail);
diff --git a/src/Files.App/Utils/Storage/Helpers/DriveHelpers.cs b/src/Files.App/Utils/Storage/Helpers/DriveHelpers.cs
index 1a16a5351ecb..61a8d16f0b31 100644
--- a/src/Files.App/Utils/Storage/Helpers/DriveHelpers.cs
+++ b/src/Files.App/Utils/Storage/Helpers/DriveHelpers.cs
@@ -163,10 +163,5 @@ public static unsafe string GetExtendedDriveLabel(SystemIO.DriveInfo drive)
 
 			}) ?? "";
 		}
-
-		public static async Task<StorageItemThumbnail> GetThumbnailAsync(StorageFolder folder)
-			=> (StorageItemThumbnail)await FilesystemTasks.Wrap(()
-				=> folder.GetThumbnailAsync(ThumbnailMode.SingleItem, 40, ThumbnailOptions.UseCurrentScale).AsTask()
-			);
 	}
 }
\ No newline at end of file
diff --git a/src/Files.App/Utils/Storage/Helpers/FileThumbnailHelper.cs b/src/Files.App/Utils/Storage/Helpers/FileThumbnailHelper.cs
index 72a838089f47..3d8e6cd68fa1 100644
--- a/src/Files.App/Utils/Storage/Helpers/FileThumbnailHelper.cs
+++ b/src/Files.App/Utils/Storage/Helpers/FileThumbnailHelper.cs
@@ -1,20 +1,56 @@
 // Copyright (c) Files Community
 // Licensed under the MIT License.
 
+using Windows.Storage;
 using Windows.Storage.FileProperties;
 
 namespace Files.App.Utils.Storage
 {
 	public static class FileThumbnailHelper
 	{
+		public static async Task<byte[]?> GetIconAsync(string? path, IStorageItem? item, uint requestedSize, bool isFolder, IconOptions iconOptions)
+		{
+			byte[]? result = null;
+			if (path is not null)
+				result ??= await GetIconAsync(path, requestedSize, isFolder, iconOptions);
+			if (item is not null)
+				result ??= await GetIconAsync(item, requestedSize, iconOptions);
+			return result;
+		}
+
 		/// <summary>
 		/// Returns icon or thumbnail for given file or folder
 		/// </summary>
-		public static async Task<byte[]?> GetIconAsync(string path, uint requestedSize, bool isFolder, IconOptions iconOptions)
+		public static Task<byte[]?> GetIconAsync(string path, uint requestedSize, bool isFolder, IconOptions iconOptions)
 		{
 			var size = iconOptions.HasFlag(IconOptions.UseCurrentScale) ? requestedSize * App.AppModel.AppWindowDPI : requestedSize;
 
-			return await Win32Helper.StartSTATask(() => Win32Helper.GetIcon(path, (int)size, isFolder, iconOptions));
+			return Win32Helper.StartSTATask(() => Win32Helper.GetIcon(path, (int)size, isFolder, iconOptions));
+		}
+
+		/// <summary>
+		/// Returns thumbnail for given file or folder using Storage API
+		/// </summary>
+		public static Task<byte[]?> GetIconAsync(IStorageItem item, uint requestedSize, IconOptions iconOptions)
+		{
+			var thumbnailOptions = (iconOptions.HasFlag(IconOptions.UseCurrentScale) ? ThumbnailOptions.UseCurrentScale : 0) |
+								   (iconOptions.HasFlag(IconOptions.ReturnOnlyIfCached) ? ThumbnailOptions.ReturnOnlyIfCached : 0) |
+								   (iconOptions.HasFlag(IconOptions.ResizeThumbnail) ? ThumbnailOptions.ResizeThumbnail : 0);
+
+			return GetIconAsync(item, requestedSize, ThumbnailMode.SingleItem, thumbnailOptions);
+		}
+
+		public static async Task<byte[]?> GetIconAsync(IStorageItem item, uint requestedSize, ThumbnailMode thumbnailMode, ThumbnailOptions thumbnailOptions)
+		{
+			using StorageItemThumbnail thumbnail = item switch
+			{
+				BaseStorageFile file => await FilesystemTasks.Wrap(() => file.GetThumbnailAsync(thumbnailMode, requestedSize, thumbnailOptions).AsTask()),
+				BaseStorageFolder folder => await FilesystemTasks.Wrap(() => folder.GetThumbnailAsync(thumbnailMode, requestedSize, thumbnailOptions).AsTask()),
+				_ => new(null!, FileSystemStatusCode.Generic)
+			};
+			if (thumbnail is not null && thumbnail.Size != 0 && thumbnail.OriginalHeight != 0 && thumbnail.OriginalWidth != 0)
+				return await thumbnail.ToByteArrayAsync();
+			return null;
 		}
 
 		/// <summary>
@@ -23,14 +59,13 @@ public static class FileThumbnailHelper
 		/// <param name="path"></param>
 		/// <param name="isFolder"></param>
 		/// <returns></returns>
-		public static async Task<byte[]?> GetIconOverlayAsync(string path, bool isFolder)
-			=> await Win32Helper.StartSTATask(() => Win32Helper.GetIconOverlay(path, isFolder));
+		public static Task<byte[]?> GetIconOverlayAsync(string path, bool isFolder)
+			=> Win32Helper.StartSTATask(() => Win32Helper.GetIconOverlay(path, isFolder));
 
 		[Obsolete]
-		public static async Task<byte[]?> LoadIconFromPathAsync(string filePath, uint thumbnailSize, ThumbnailMode thumbnailMode, ThumbnailOptions thumbnailOptions, bool isFolder = false)
+		public static Task<byte[]?> LoadIconFromPathAsync(string filePath, uint thumbnailSize, ThumbnailMode thumbnailMode, ThumbnailOptions thumbnailOptions, bool isFolder = false)
 		{
-			var result = await GetIconAsync(filePath, thumbnailSize, isFolder, IconOptions.None);
-			return result;
+			return GetIconAsync(filePath, thumbnailSize, isFolder, IconOptions.None);
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/Files.App/Utils/Storage/Search/FolderSearch.cs b/src/Files.App/Utils/Storage/Search/FolderSearch.cs
index 08df6e230def..940869a0abe8 100644
--- a/src/Files.App/Utils/Storage/Search/FolderSearch.cs
+++ b/src/Files.App/Utils/Storage/Search/FolderSearch.cs
@@ -512,6 +512,7 @@ private async Task<ListedItem> GetListedItemAsync(IStorageItem item)
 			{
 				var iconResult = await FileThumbnailHelper.GetIconAsync(
 					item.Path,
+					item,
 					Constants.ShellIconSizes.Small,
 					item.IsOfType(StorageItemTypes.Folder),
 					IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
diff --git a/src/Files.App/ViewModels/Properties/Items/DriveProperties.cs b/src/Files.App/ViewModels/Properties/Items/DriveProperties.cs
index 750ac63b8ed0..8fc2c45c5c07 100644
--- a/src/Files.App/ViewModels/Properties/Items/DriveProperties.cs
+++ b/src/Files.App/ViewModels/Properties/Items/DriveProperties.cs
@@ -52,6 +52,7 @@ public async override Task GetSpecialPropertiesAsync()
 			{
 				var result = await FileThumbnailHelper.GetIconAsync(
 					Drive.Path,
+					diskRoot,
 					Constants.ShellIconSizes.ExtraLarge,
 					true,
 					IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
diff --git a/src/Files.App/ViewModels/Properties/Items/FileProperties.cs b/src/Files.App/ViewModels/Properties/Items/FileProperties.cs
index d0de82a45d27..1d46b316b464 100644
--- a/src/Files.App/ViewModels/Properties/Items/FileProperties.cs
+++ b/src/Files.App/ViewModels/Properties/Items/FileProperties.cs
@@ -108,8 +108,13 @@ public override async Task GetSpecialPropertiesAsync()
 				ViewModel.ItemSizeOnDisk = Win32Helper.GetFileSizeOnDisk(Item.ItemPath)?.ToLongSizeString() ??
 				   string.Empty;
 
+			string filePath = (Item as ShortcutItem)?.TargetPath ?? Item.ItemPath;
+			BaseStorageFile? file = !string.IsNullOrWhiteSpace(filePath) ?
+				await AppInstance.ShellViewModel.GetFileFromPathAsync(filePath) : null!;
+
 			var result = await FileThumbnailHelper.GetIconAsync(
 				Item.ItemPath,
+				file,
 				Constants.ShellIconSizes.ExtraLarge,
 				false,
 				IconOptions.UseCurrentScale);
@@ -132,9 +137,6 @@ public override async Task GetSpecialPropertiesAsync()
 				}
 			}
 
-			string filePath = (Item as ShortcutItem)?.TargetPath ?? Item.ItemPath;
-			BaseStorageFile file = await AppInstance.ShellViewModel.GetFileFromPathAsync(filePath);
-
 			// Couldn't access the file and can't load any other properties
 			if (file is null)
 				return;
@@ -152,7 +154,7 @@ public override async Task GetSpecialPropertiesAsync()
 						ViewModel.UncompressedItemSizeBytes = uncompressedSize;
 					}
 
-			if (file.Properties is not null)
+			if (file?.Properties is not null)
 				GetOtherPropertiesAsync(file.Properties);
 		}
 
diff --git a/src/Files.App/ViewModels/Properties/Items/FolderProperties.cs b/src/Files.App/ViewModels/Properties/Items/FolderProperties.cs
index 0dd47ef2610a..eec92284556c 100644
--- a/src/Files.App/ViewModels/Properties/Items/FolderProperties.cs
+++ b/src/Files.App/ViewModels/Properties/Items/FolderProperties.cs
@@ -79,8 +79,13 @@ public async override Task GetSpecialPropertiesAsync()
 			ViewModel.CanCompressContent = Win32Helper.CanCompressContent(Item.ItemPath);
 			ViewModel.IsContentCompressed = Win32Helper.HasFileAttribute(Item.ItemPath, System.IO.FileAttributes.Compressed);
 
+			string folderPath = (Item as ShortcutItem)?.TargetPath ?? Item.ItemPath;
+			BaseStorageFolder? storageFolder = !string.IsNullOrWhiteSpace(folderPath) ? 
+				await AppInstance.ShellViewModel.GetFolderFromPathAsync(folderPath) : null!;
+
 			var result = await FileThumbnailHelper.GetIconAsync(
 				Item.ItemPath,
+				storageFolder,
 				Constants.ShellIconSizes.ExtraLarge,
 				true,
 				IconOptions.UseCurrentScale);
@@ -111,9 +116,6 @@ public async override Task GetSpecialPropertiesAsync()
 				}
 			}
 
-			string folderPath = (Item as ShortcutItem)?.TargetPath ?? Item.ItemPath;
-			BaseStorageFolder storageFolder = await AppInstance.ShellViewModel.GetFolderFromPathAsync(folderPath);
-
 			if (storageFolder is not null)
 			{
 				ViewModel.ItemCreatedTimestampReal = storageFolder.DateCreated;
diff --git a/src/Files.App/ViewModels/ShellViewModel.cs b/src/Files.App/ViewModels/ShellViewModel.cs
index 3538ce53f269..32a9ffe2ac6a 100644
--- a/src/Files.App/ViewModels/ShellViewModel.cs
+++ b/src/Files.App/ViewModels/ShellViewModel.cs
@@ -973,7 +973,7 @@ private async Task<BitmapImage> GetShieldIcon()
 			return shieldIcon;
 		}
 
-		private async Task LoadThumbnailAsync(ListedItem item, CancellationToken cancellationToken)
+		private async Task<bool> LoadThumbnailAsync(ListedItem item, CancellationToken cancellationToken)
 		{
 			var loadNonCachedThumbnail = false;
 			var thumbnailSize = LayoutSizeKindHelper.GetIconSize(folderSettings.LayoutMode);
@@ -1086,6 +1086,43 @@ await dispatcherQueue.EnqueueOrInvokeAsync(async () =>
 					}
 				}, cancellationToken);
 			}
+
+			return result is not null;
+		}
+
+		private async Task<bool> LoadThumbnailAsync(ListedItem item, IStorageItem matchingStorageItem, CancellationToken cancellationToken)
+		{
+			var thumbnailSize = LayoutSizeKindHelper.GetIconSize(folderSettings.LayoutMode);
+			// SingleItem returns image thumbnails in the correct aspect ratio for the grid layouts
+			// ListView is used for the details and columns layout
+			// We use ReturnOnlyIfCached because otherwise folders thumbnails have a black background, this has the downside the folder previews don't work
+			var (mode, options) = matchingStorageItem switch
+			{
+				BaseStorageFolder => (ThumbnailMode.SingleItem, ThumbnailOptions.ReturnOnlyIfCached),
+				BaseStorageFile when thumbnailSize < 96 => (ThumbnailMode.ListView, ThumbnailOptions.ResizeThumbnail),
+				_ => (ThumbnailMode.SingleItem, ThumbnailOptions.ResizeThumbnail),
+			};
+
+			var result = await FileThumbnailHelper.GetIconAsync(
+						matchingStorageItem, 
+						thumbnailSize,
+						mode,
+						options);
+
+			if (result is not null)
+			{
+				await dispatcherQueue.EnqueueOrInvokeAsync(async () =>
+				{
+					// Assign FileImage property
+					var image = await result.ToBitmapAsync();
+					if (image is not null)
+						item.FileImage = image;
+				}, Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal);
+
+				return true;
+			}
+
+			return false;
 		}
 
 		private static void SetFileTag(ListedItem item)
@@ -1128,7 +1165,7 @@ public async Task LoadExtendedItemPropertiesAsync(ListedItem item)
 					}
 
 					cts.Token.ThrowIfCancellationRequested();
-					await LoadThumbnailAsync(item, cts.Token);
+					var wasThumbnailLoaded = await LoadThumbnailAsync(item, cts.Token);
 
 					cts.Token.ThrowIfCancellationRequested();
 					if (item.IsLibrary || item.PrimaryItemAttribute == StorageItemTypes.File || item.IsArchive)
@@ -1180,6 +1217,10 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
 								},
 								Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
 
+								// For MTP devices load thumbnail using Storage API (#15084)
+								if (!wasThumbnailLoaded)
+									await LoadThumbnailAsync(item, matchingStorageFile, cts.Token);
+
 								SetFileTag(item);
 								wasSyncStatusLoaded = true;
 							}
@@ -1250,6 +1291,10 @@ await dispatcherQueue.EnqueueOrInvokeAsync(() =>
 								},
 								Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
 
+								// For MTP devices load thumbnail using Storage API (#15084)
+								if (!wasThumbnailLoaded)
+									await LoadThumbnailAsync(item, matchingStorageFolder, cts.Token);
+
 								SetFileTag(item);
 								wasSyncStatusLoaded = true;
 							}
diff --git a/src/Files.App/ViewModels/UserControls/Previews/BasePreviewModel.cs b/src/Files.App/ViewModels/UserControls/Previews/BasePreviewModel.cs
index 28f3a26cefd6..e42111fefa22 100644
--- a/src/Files.App/ViewModels/UserControls/Previews/BasePreviewModel.cs
+++ b/src/Files.App/ViewModels/UserControls/Previews/BasePreviewModel.cs
@@ -86,6 +86,7 @@ public async virtual Task<List<FileProperty>> LoadPreviewAndDetailsAsync()
 		{
 			var result = await FileThumbnailHelper.GetIconAsync(
 				Item.ItemPath,
+				Item.ItemFile,
 				Constants.ShellIconSizes.Jumbo,
 				false,
 				IconOptions.None);
diff --git a/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs b/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs
index f4a2d746a3d1..20be89f82dae 100644
--- a/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs
+++ b/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs
@@ -29,6 +29,7 @@ private async Task LoadPreviewAndDetailsAsync()
 
 			var result = await FileThumbnailHelper.GetIconAsync(
 				Item.ItemPath,
+				Folder,
 				Constants.ShellIconSizes.Jumbo,
 				true,
 				IconOptions.None);