From e38e8cf01a9aaadbae7dfb97dab8e26a06ad0baf Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Fri, 11 Jul 2025 20:38:12 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=89=A9=E5=93=81?= =?UTF-8?q?=E5=9B=BE=E6=98=BE=E7=A4=BA=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MaaWpfGui/Helper/ItemListHelper.cs | 87 ++++++++++++------- .../ViewModels/UI/RecognizerViewModel.cs | 15 +--- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/MaaWpfGui/Helper/ItemListHelper.cs b/src/MaaWpfGui/Helper/ItemListHelper.cs index 7d1576364d..0638e305f5 100644 --- a/src/MaaWpfGui/Helper/ItemListHelper.cs +++ b/src/MaaWpfGui/Helper/ItemListHelper.cs @@ -14,6 +14,7 @@ #nullable enable using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Text.Json; @@ -84,56 +85,80 @@ namespace MaaWpfGui.Helper : itemId; } + private static readonly ConcurrentDictionary _imageCache = new(); + /// /// 获取对应物品的图标 / Get the icon of the corresponding item /// /// 物品 id / Item id /// 物品图片 - public static BitmapImage? GetItemImage(string itemId) + public static BitmapSource? GetItemImage(string itemId) { + if (_imageCache.TryGetValue(itemId, out var cachedImage)) + { + return cachedImage; + } + var imagePath = Path.Combine(Environment.CurrentDirectory, $"resource/template/items/{itemId}.png"); if (!File.Exists(imagePath)) { + _imageCache.TryAdd(itemId, null); return null; } try { - var bitmapImage = new BitmapImage(new(imagePath, UriKind.RelativeOrAbsolute)); - - var stride = bitmapImage.PixelWidth * ((bitmapImage.Format.BitsPerPixel + 7) / 8); - var pixelData = new byte[stride * bitmapImage.PixelHeight]; - bitmapImage.CopyPixels(pixelData, stride, 0); - - // 把黑边变成透明(其实是所有的黑色都变成透明了x - for (int i = 0; i < pixelData.Length; i += 4) - { - if (pixelData[i] == 0 && pixelData[i + 1] == 0 && pixelData[i + 2] == 0) - { - pixelData[i + 3] = 0; - } - } - - // 不知道为啥 WriteableBitmap(bitmapImage); 得到的图没有透明度,大概是原始 uri 对应的是个 24 位的图?手动处理一下 - var writeableBitmap = new WriteableBitmap(bitmapImage.PixelWidth, bitmapImage.PixelHeight, bitmapImage.DpiX, bitmapImage.DpiY, PixelFormats.Bgra32, null); - writeableBitmap.WritePixels(new(0, 0, bitmapImage.PixelWidth, bitmapImage.PixelHeight), pixelData, stride, 0); - - bitmapImage = new(); - using MemoryStream stream = new MemoryStream(); - PngBitmapEncoder encoder = new PngBitmapEncoder(); - encoder.Frames.Add(BitmapFrame.Create(writeableBitmap)); - encoder.Save(stream); - bitmapImage.BeginInit(); - bitmapImage.CacheOption = BitmapCacheOption.OnLoad; - bitmapImage.StreamSource = stream; - bitmapImage.EndInit(); - bitmapImage.Freeze(); - return bitmapImage; + var processedImage = ProcessBlackToTransparent(imagePath); + _imageCache.TryAdd(itemId, processedImage); + return processedImage; } catch { + _imageCache.TryAdd(itemId, null); return null; } } + + private static BitmapSource ProcessBlackToTransparent(string imagePath) + { + var original = new BitmapImage(); + original.BeginInit(); + original.CacheOption = BitmapCacheOption.OnLoad; + original.UriSource = new(imagePath, UriKind.RelativeOrAbsolute); + original.EndInit(); + + var convertedBitmap = new FormatConvertedBitmap(original, PixelFormats.Bgra32, null, 0); + var writeable = new WriteableBitmap(convertedBitmap); + + writeable.Lock(); + try + { + unsafe + { + var pixels = (uint*)writeable.BackBuffer; + int pixelCount = writeable.PixelWidth * writeable.PixelHeight; + + for (int i = 0; i < pixelCount; i++) + { + uint pixel = pixels[i]; + uint bgr = pixel & 0x00FFFFFF; + + if (bgr == 0) + { + pixels[i] = 0x00000000; + } + } + } + + writeable.AddDirtyRect(new(0, 0, writeable.PixelWidth, writeable.PixelHeight)); + } + finally + { + writeable.Unlock(); + } + + writeable.Freeze(); + return writeable; + } } } diff --git a/src/MaaWpfGui/ViewModels/UI/RecognizerViewModel.cs b/src/MaaWpfGui/ViewModels/UI/RecognizerViewModel.cs index 1c22e55a78..6d6f2eee4c 100644 --- a/src/MaaWpfGui/ViewModels/UI/RecognizerViewModel.cs +++ b/src/MaaWpfGui/ViewModels/UI/RecognizerViewModel.cs @@ -354,7 +354,7 @@ namespace MaaWpfGui.ViewModels.UI public string Id { get; set; } = null!; - public BitmapImage? Image { get; set; } + public BitmapSource? Image { get; set; } public string? Count { get; set; } } @@ -398,11 +398,6 @@ namespace MaaWpfGui.ViewModels.UI /// public string LoliconResult { get; set; } = string.Empty; - /// - /// gets or sets the depot image. - /// - private static readonly Dictionary _imageCache = new(); - /// /// parse of depot recognition result /// @@ -430,17 +425,11 @@ namespace MaaWpfGui.ViewModels.UI continue; } - if (!_imageCache.TryGetValue(id, out var image)) - { - image = ItemListHelper.GetItemImage(id); - _imageCache[id] = image; - } - DepotResultDate result = new() { Id = id, Name = ItemListHelper.GetItemName(id), - Image = image, + Image = ItemListHelper.GetItemImage(id), Count = item["have"] != null && int.TryParse(item["have"]?.ToString() ?? "-1", out int haveValue) ? (haveValue > 10000 ? $"{haveValue / 10000.0:F1}w"