Отображение большого изображения, совершенно разное использование памяти на разных компьютерах [закрыто]C#

Место общения программистов C#
Ответить
Anonymous
 Отображение большого изображения, совершенно разное использование памяти на разных компьютерах [закрыто]

Сообщение Anonymous »

Я показываю большое изображение в приложении 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 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;
}
}
}
Я надеялся, что можно будет плавно прокручивать все изображение. Я не вижу причины, по которой некоторые машины работают нормально, а другие нет.
Чтобы создать тестовое приложение, создайте приложение .NET WPF под названием GenerateFilmstrip в Visual Studio и замените MainWindow.xaml и .cs приведенным выше кодом. Я использую .NET 9, но и другие должны работать.

Подробнее здесь: https://stackoverflow.com/questions/797 ... ferent-pcs
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»