WPF大图像显示在不同配置PC上内存占用差异巨大的问题求助
WPF大图像显示在不同配置PC上内存占用差异巨大的问题求助
大家好,我遇到一个挺棘手的问题,想请教下各位大佬。我在WPF应用里显示一张108000x960像素的超大图像,在两台笔记本上运行很顺畅:内存占用大概1GB左右,CPU使用率不到5%,滚动图像也丝滑流畅。但在另外两台机器上,滚动时内存会疯涨到10GB以上,应用直接卡得没法用。
所有机器的基础配置一致:16GB内存、Intel Iris Xe核显、1080p显示器、Windows 11 Home系统,具体差异如下:
- 正常运行的两台:搭载i5-11320H和i5-1145G7处理器,其中一台是单条SODIMM内存,另一台是双条,内存规格都是DDR4 3200
- 出问题的两台:搭载i5-1340P和Core Ultra 7 155H处理器,Core Ultra机型用的是LPDDR5X 6400 MT/s内存,另一台是DDR4 3200双条
我知道这图像尺寸确实很大,一开始在主力台式机开发完,放到笔记本测试正常还挺庆幸的,结果换最新的笔记本就翻车了,内存暴涨还卡顿。下面是我写的简单测试应用代码,麻烦帮忙看看问题出在哪?
MainWindow.xaml
<Window x:Class="GenerateFilmstrip.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="Filmstrip" SizeToContent="WidthAndHeight" WindowStartupLocation="Manual" Top="0" Left="20"> <ScrollViewer HorizontalScrollBarVisibility="Visible" Width="1080" VerticalScrollBarVisibility="Hidden" > <Image x:Name="FilmstripImage" Stretch="None" Height="960" /> </ScrollViewer> </Window>
MainWindow.xaml.cs
using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; namespace GenerateFilmstrip { public partial class MainWindow : Window { private readonly Pen penWhite = new(Brushes.White, 5.0); public MainWindow() { InitializeComponent(); LoadFilmstrip(); } private void LoadFilmstrip() { int imageHeight = 960; FilmstripImage.Height = imageHeight; BitmapSource filmstrip = GenerateFilmstrip( frameCount: 100, frameWidth: 1080, frameHeight: imageHeight, rectWidth: 300, rectHeight: 600, cornerRadius: 20); FilmstripImage.Source = filmstrip; } private RenderTargetBitmap GenerateFilmstrip(int frameCount, int frameWidth, int frameHeight, int rectWidth, int rectHeight, double cornerRadius) { int filmstripWidth = frameCount * frameWidth; int filmstripHeight = frameHeight; DrawingVisual drawingVisual = new(); using (DrawingContext drawingContext = drawingVisual.RenderOpen()) { drawingContext.DrawRectangle(Brushes.Black, null, new Rect(0, 0, filmstripWidth, filmstripHeight)); for (int frame = 0; frame < frameCount; frame++) DrawFrame(drawingContext, frame, frameCount, frameWidth, frameHeight, rectWidth, rectHeight, cornerRadius); } return CreateBitmapFromVisual(drawingVisual, filmstripWidth, filmstripHeight); } private void DrawFrame(DrawingContext drawingContext, int frameIndex, int totalFrames, int frameWidth, int frameHeight, int rectWidth, int rectHeight, double cornerRadius) { double frameX = frameIndex * frameWidth; double rotationAngle = (double)frameIndex / totalFrames * 360.0; Color rectangleColor = GetCyclingColor(frameIndex, totalFrames); SolidColorBrush rectangleBrush = new(rectangleColor); double rectX = frameX + (frameWidth - rectWidth) / 2.0; double rectY = (frameHeight - rectHeight) / 2.0; TransformGroup transformGroup = new(); double centerX = rectX + rectWidth / 2.0; double centerY = rectY + rectHeight / 2.0; transformGroup.Children.Add(new RotateTransform(rotationAngle, centerX, centerY)); drawingContext.PushTransform(transformGroup); Rect rectangleBounds = new(rectX, rectY, rectWidth, rectHeight); drawingContext.DrawRoundedRectangle(rectangleBrush, penWhite, rectangleBounds, cornerRadius, cornerRadius); drawingContext.Pop(); } private static Color GetCyclingColor(int frameIndex, int totalFrames) { double hue = (double)frameIndex / totalFrames * 360.0; return HsvToRgb(hue, 1.0, 1.0); } private static Color HsvToRgb(double hue, double saturation, double value) { int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6; double f = hue / 60 - Math.Floor(hue / 60); value *= 255; byte v = Convert.ToByte(value); byte p = Convert.ToByte(value * (1 - saturation)); byte q = Convert.ToByte(value * (1 - f * saturation)); byte t = Convert.ToByte(value * (1 - (1 - f) * saturation)); return hi switch { 0 => Color.FromRgb(v, t, p), 1 => Color.FromRgb(q, v, p), 2 => Color.FromRgb(p, v, t), 3 => Color.FromRgb(p, q, v), 4 => Color.FromRgb(t, p, v), _ => Color.FromRgb(v, p, q), }; } private RenderTargetBitmap CreateBitmapFromVisual(DrawingVisual visual, int width, int height) { RenderTargetBitmap renderTargetBitmap = new(width, height, 96, 96, PixelFormats.Pbgra32); renderTargetBitmap.Render(visual); renderTargetBitmap.Freeze(); return renderTargetBitmap; } } }
内容来源于stack exchange
相关产品推荐
相关产品推荐

