Laden...

Übergroße Bitmaps erstellen

Erstellt von garados001 vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.300 Views
G
garados001 Themenstarter:in
33 Beiträge seit 2012
vor 10 Jahren
Übergroße Bitmaps erstellen

Ich habe mal eine einfache Frage:
Ist es irgendwie möglich übergroße Bitmaps (>10k x 10 k --> 100MP) zu erstellen? Wenn ja, würde es auch zu speichern gehen und/ oder in eine PictureBox passen?

Will man nun eine Bitmap dieser Größe auf normalen Wege erstellen kommt es zu einen unbekannten Fehler in der GDI+. Wo liegt denn hier dabei das Problem?


//Beispielcode
int width = 12000, height = 16000;
var b = new Bitmap(width, height);

(Wenn es nicht geht, ist es auch nicht so schlimm. Muss dann nur ein paar Einschränkungen hinzufügen)

16.807 Beiträge seit 2008
vor 10 Jahren

kommt es zu einen unbekannten Fehler in der GDI+. Wo liegt denn hier dabei das Problem? [Hinweis] Wie poste ich richtig? Punkt 5
Wenn Du die Exception in die Forensuche tippst wirst Du den GDI-Fehler vermutlichn finden bzw. viele Treffer haben. Ist üblich bei GDI.

~~Trotzdem sei gesagt: der GC Heap liegt bei maximal 2 GB bei .NET. ~~Auch wenn die Datei rechnerisch dann 300MB groß ist (RGB 24bit/px) könntest Du mit 100MP locker den verfügbaren Heap sprengen.

Es gibt mit ImageMagick.NET ein API, die riesige Bilder generieren / bearbeiten kann (tera pixel).
Nich mehr die neueste aber vllt klappts damit.

742 Beiträge seit 2005
vor 10 Jahren

Die maximale Objektgröße ist doch 2GB, nicht die Heap-Größe.

12000x16000x32bit = 700 MB (+/-), sollte also passen und tut bei mir auch. Hast du davor schon ein paar Bilder erstellt? Eventuell geht dann wirklich der Heap alle, weil das Bild zu groß ist und im Large-Object-Heap liegt. Objekte in diesem Speicherbereich werden nicht verschoben, es kann also passieren, dass dein Speicher zu sehr fragmentiert ist.

G
garados001 Themenstarter:in
33 Beiträge seit 2012
vor 10 Jahren

Naja es ist ein Programm für den Kunstunterricht (der Lehrer nennt so etwas "Joiner"). Da kann es vorkommen, dass dabei rießige Bilder entstehen. Die Zahl 12000x16000 war eher zufällig gewählt. Ich habe es mal mit einer extremen (es ist theoretisch noch extremer möglich) aber realistischen Variante ausprobiert. Dabei waren es 19.200x12.000 (230 MPixel). So etwas eignet sich zwar eher um A2 Plakate auszufüllen (also nicht für den Hausgebrauch).

Ich hatte mal den Tipp mit der Magick.NET API ausprobiert. Das Problem ist nur, dass es ewig lange braucht, um die Bilder zusammen zu addieren.


//s ist die Rastergröße (hier 192x120)
//TargetSize ist die Größe der einzelnen Elemente (hier 100x100)
//ResultCollection ist ein Array aus verschiedenen Bitmaps, die in das Raster sollen
var b = new MagickImage(new MagickColor(Color.Transparent), s.Width * TargetSize.Width, s.Height * TargetSize.Height);
for (int x = 0; x < s.Width; ++x) for (int y = 0; y < s.Height; ++y)
{
    b.Composite(new MagickImage(ResultCollection[x, y].Image), x * TargetSize.Width, y * TargetSize.Height, CompositeOperator.Replace);
    Invoke(new Action<int, int>((ak, mx) => { progressBar1.Maximum = mx; progressBar1.Value = ak; }), x * s.Height, s.Width * s.Height);
}

Kann man das für meine Zwecke optimieren?

1.346 Beiträge seit 2008
vor 10 Jahren

Ich würde bei diesen Anforderungen manuell arbeiten. Mit der MemoryMappedFile-Klasse. Dann kann sich das Betriebssystem darum kümmern was im Ram und was auf der Platte liegt. Zum Anzeigen müsstest du dann eine kleinere Kopie für den Ram erzeugen. Das sollte aber halb so wild sein

G
garados001 Themenstarter:in
33 Beiträge seit 2012
vor 10 Jahren

Danke, das mit den MemoryMappedFile hat mir geholfen. Ist jetzt zwar schneller, aber nicht unbedingt, dass schnellste. Ich werde jetzt noch ein wenig Code umschreiben, vielleicht wird es dann besser (die Bilder zeilenweise addieren, statt jedes Bild einzeln). Dennoch ist es etwas was sinnvoll ist.
Nur muss mich jetzt leider belesen, wie die einzelnen Formate gespeichert werden (also ich habe es mit bmp ausprobiert, und Top Ergebnisse erzielt, aber 675MB für 230MP), aber das sollte gehen.

Was mich aber wundert ist, dass die Windows-Foto-Anzeige, dieses Bild ohne große Probleme darstellen kann (aber ohne den RAM vollzumüllen [18,3MB benutzt er])!

C
1.214 Beiträge seit 2006
vor 10 Jahren

Das wird kompliziert, wenn du alle wichtigen Rastergrafikformate unterstützten willst.

Ich kenne ImageMagick.NET jetzt nicht und ich kann nicht einschätzen, ob das was du damit gemacht hast nicht vielleicht falsch ist, oder ob das am Wrapper, an der Version, oder an sonst was liegt. Aber grundsätzlich sollte ImageMagick schon ziemlich schnell sein, die Software ist ziemlich bekannt und wird auch aktiv entwickelt. Deswegen würde ich mal die neueste Version installieren und damit etwas auf der Kommandozeile rumspielen, um die Ergebnisse zu vergleichen. Wenn das brauchbare Ergebnisse liefert, kannst du ja vielleicht die API etwas genauer untersuchen, ob das nicht irgendwie schneller geht. Oder ob du das nicht auch vielleicht irgendwie anders einsetzen kannst.

G
garados001 Themenstarter:in
33 Beiträge seit 2012
vor 10 Jahren

Ich habe ImageMagick.NET eher eine schlechte Performance erreicht. Lag wahrscheinlich auch daran, dass die Festplatte zu 100% ausgelastet war und ich keine SSD habe. Die andere Variante war da schon schneller.

C
1.214 Beiträge seit 2006
vor 10 Jahren

Lies nochmal, was ich geschrieben habe.