Anzeige eines großen Bildes, völlig unterschiedliche Speichernutzung auf verschiedenen PCs [geschlossen]C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Anzeige eines großen Bildes, völlig unterschiedliche Speichernutzung auf verschiedenen PCs [geschlossen]

Post by Anonymous »

Ich zeige ein großes Bild in einer WPF-App an. 108000 x 960 Pixel. Es funktioniert gut auf einigen Laptops – verbraucht etwa 1 GB RAM, weniger als 5 % CPU, scrollt reibungslos über das Bild. Aber auf zwei anderen Maschinen steigt die Speichernutzung beim Scrollen schnell auf über 10 GB an und die App wird langsamer.
Alle Maschinen verfügen über 16 GB RAM mit Intel Iris Xe iGPUs, 1080p-Displays und Windows 11 Home. Eine der funktionierenden Maschinen verfügt nur über ein einziges SODIMM, die anderen über zwei Module.
Die beiden gut funktionierenden Laptops verfügen über einen Intel i5-11320H und einen i5-1145G7. Die beiden, die Probleme haben, sind ein i5-1340P und ein Core Ultra 7 155H. Der Core Ultra verfügt über LPDDR5X 6400 MT/s RAM, der Rest über DRR4 3200.
Mir ist klar, dass es sich um ein sehr großes Bild handelt. Nachdem ich es auf meinem Haupt-Desktop-Rechner entwickelt hatte, habe ich es auf einem Laptop ausprobiert und war erleichtert, dass es gut funktionierte. Später habe ich es jedoch auf meinem neuesten Laptop versucht und es war nicht in Ordnung – großer Speicherverbrauch und langsam.
Hier ist eine einfache Test-App:
MainWindow.xaml

Code: Select all






MainWindow.xaml.cs

Code: Select all

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;
}
}
}
Ich hatte gehofft, dass man reibungslos durch das gesamte Bild scrollen kann. Ich kann keinen Grund dafür erkennen, dass einige Maschinen einwandfrei funktionieren und andere nicht.
Um die Test-App zu erstellen, erstellen Sie eine .NET WPF-App namens GenerateFilmstrip in Visual Studio und ersetzen Sie MainWindow.xaml und .cs durch den obigen Code. Ich verwende .NET 9, aber andere sollten funktionieren.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post