Я показываю большое изображение в приложении WPF. 108000x960 пикселей. Он хорошо работает на паре ноутбуков — использует около 1 ГБ оперативной памяти, менее 5% процессора, плавно прокручивает изображение. Но на двух других машинах использование памяти быстро возрастает до более чем 10 ГБ при прокрутке и приложение замедляется.
Все машины имеют 16 ГБ оперативной памяти с iGPU Intel Iris Xe, дисплеями 1080p и Windows 11 Home. Одна из работающих машин имеет только один модуль SODIMM, остальные имеют 2 модуля.
Два ноутбука, которые работают хорошо, имеют Intel i5-11320H и i5-1145G7. Проблемы есть у i5-1340P и Core Ultra 7 155H. Core Ultra имеет оперативную память LPDDR5X 6400 МТ/с, остальные — DRR4 3200.
Я понимаю, что это очень большой образ, поэтому после разработки на своем основном настольном компьютере я попробовал его на ноутбуке и с облегчением увидел, что он работает нормально. Однако позже я попробовал на своем последнем ноутбуке, и он оказался не в порядке — большое использование памяти и медленная работа.
Вот простое тестовое приложение:
MainWindow.xaml
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;
}
}
}
Я надеялся, что можно будет плавно прокручивать все изображение. Я не вижу причины, по которой некоторые машины работают нормально, а другие нет.
Чтобы создать тестовое приложение, создайте приложение .NET WPF под названием GenerateFilmstrip в Visual Studio и замените MainWindow.xaml и .cs приведенным выше кодом. Я использую .NET 9, но и другие должны работать.
Я показываю большое изображение в приложении WPF. 108000x960 пикселей. Он хорошо работает на паре ноутбуков — использует около 1 ГБ оперативной памяти, менее 5% процессора, плавно прокручивает изображение. Но на двух других машинах использование памяти быстро возрастает до более чем 10 ГБ при прокрутке и приложение замедляется. Все машины имеют 16 ГБ оперативной памяти с iGPU Intel Iris Xe, дисплеями 1080p и Windows 11 Home. Одна из работающих машин имеет только один модуль SODIMM, остальные имеют 2 модуля. Два ноутбука, которые работают хорошо, имеют Intel i5-11320H и i5-1145G7. Проблемы есть у i5-1340P и Core Ultra 7 155H. Core Ultra имеет оперативную память LPDDR5X 6400 МТ/с, остальные — DRR4 3200. Я понимаю, что это очень большой образ, поэтому после разработки на своем основном настольном компьютере я попробовал его на ноутбуке и с облегчением увидел, что он работает нормально. Однако позже я попробовал на своем последнем ноутбуке, и он оказался не в порядке — большое использование памяти и медленная работа. Вот простое тестовое приложение: MainWindow.xaml [code]
[/code] MainWindow.xaml.cs [code]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 RenderTargetBitmap GenerateFilmstrip(int frameCount, int frameWidth, int frameHeight, int rectWidth, int rectHeight, double cornerRadius) { int filmstripWidth = frameCount * frameWidth; int filmstripHeight = frameHeight;
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; } } } [/code] Я надеялся, что можно будет плавно прокручивать все изображение. Я не вижу причины, по которой некоторые машины работают нормально, а другие нет. Чтобы создать тестовое приложение, создайте приложение .NET WPF под названием GenerateFilmstrip в Visual Studio и замените MainWindow.xaml и .cs приведенным выше кодом. Я использую .NET 9, но и другие должны работать.