C# Grafikobjekt aus indiziertem Bild erstellen

AP Nova

Commander
Registriert
Juni 2008
Beiträge
2.256
Ich mache es kurz:
Ein Bild, nehmen wir einfach mal eine gif-Datei, wird mittels "Bitmap Bitmapname = new Bitmap(Filestreamname);" geöffnet. Jetzt möchte ich mittels "Graphics Graphicname = Graphics.FromImage(Bitmapname);" das Bild zu einem Graphics-Objekt machen, was natürlich nicht geht, da eine indizierte Farbtabelle vorliegt.

Nach Lösungen habe ich gesucht, so viel findet man dazu nicht und selbst wenn führte das bei mir zu der Meldung, dass mir angeblich der Arbeitsspeicher ausgeht, was ich bei über 2 freien GB und dem simplen Klonen einer nicht mal 4 kB Datei ein wenig bezweifle.

Wie bekomme ich nun ein nicht indiziertes Bild für mein Graphics-Objekt?


Kleine Frage am Rande: Ist es performancetechnisch schlecht, das Graphics-Objekt direkt auf eine Bitmap zeichnen zu lassen und die Bitmap nach jedem Zeichnen als Bild der PictureBox festzulegen? Wäre es klüger, das Graphics-Objekt direkt auf die PictureBox zeichnen zu lassen und beim Speichern eine Bitmap aus dem Graphics-Objekt zu machen?

Danke für eure Hilfe
Ergänzung ()

So langsam bin ich wirklich am verzweifeln. Nachdem meine zwischenzeitliche Idee, das über "Bitmapname.Save(MemoryStreamName, ImageFormat.Bmp);" zu realisieren und dann erneut aus dem MemoryStream auszulesen aufgrund der Tatsache gescheitert ist, dass dann bei erwähntem Befehl ein "allgemeiner GDI+ Fehler" auftrat, ärgere ich mich nun weiter mit .Clone() rum.

Sieht hier vielleicht irgendjemand von euch einen Fehler, der eine OutOfMemoryException auslösen könnte?

Code:
static bitmap bmp, bmp2;

...

bmp2 = new Bitmap(FileStreamName);
bmp = bmp2.Clone(new Rectangle(0, 0, bmp2.Width, bmp2.Height), PixelFormat.Format24bppRgb);

Ich kann doch wohl kaum außerhalb der Quellbitmapgrenzen liegen, wenn ich bei 0|0 starte und die Maße der Quelle wähle. Auch 0|0 und jeweils 10 Pixel Kantenlänge oder dergleichen haben nicht funktioniert.
 
Zuletzt bearbeitet:
Also die Exception "OutOfMemory" ist IMMER ein klares Zeichen dafür das du außerhalb der Grenzen Clonen willst. Was willst du genau erreichen? Willst du nur einen Bildbereich des Bildes rausholen? Willst du es in einer GUI anzeigen, wenn ja, welche(WPF,WinForms)?
 
Wie gesagt habe ich ein Bild, welches ich aus einem FileStream auslese (wie du oben sehen kannst) und dann möchte ich das Bild einfach nur in eine andere Bitmap packen und dabei von der indizierten Tabelle wegkommen. Das andere Bild soll dann später als Image einer PictureBox dienen, aber so weit komme ich ja gar nicht, da ich erwähnte Exception bekomme, sobald ich mit genau dem oben stehendem Code (und einer Million Abwandlungen davon, die alle hätten funktionieren müssen) versuche, das zweite Bild mit angegebenem PixelFormat in das erste zu klonen.

Das ganze läuft in einer WinForms Anwendung, aber wie gesagt, so weit komme ich ja nicht einmal. Der einzig relevante Code sollte der sein, den ich oben gepostet habe. Das Auslesen des einen Bildes aus dem FileStream (was klappt) und dann das Klonen, welches erwähnte Exception verursacht obwohl ich Koordinaten nehme, die unter Garantie im Quellbild vorliegen.

Auch folgender Codeausschnitt noch vor dem Klonen zeigt sich nicht hilfreich.
Code:
bmp = new Bitmap(bmp2.Width, bmp2.Height, PixelFormat.Format24bppRgb);

edit: Bei folgendem Code kann er anscheinend Klonen, allerdings taucht dann später ein mir unerklärliches Problem auf, an dem ich jetzt aber erst einmal selbst arbeiten werden.
Code:
bmp2 = new Bitmap(FS);
bmp = bmp2.Clone(new Rectangle(0, 0, bmp2.Width, bmp2.Height), PixelFormat.Format24bppRgb);
FS.Close();
Davor hatte ich das "FS.Close();" noch vor dem Klonen platziert.
 
Zuletzt bearbeitet:
Ok gut was ich noch als Idee habe ist das PixelFormat. Mach das mal bitte so:

Code:
bmp = new Bitmap(bmp2.Width, bmp2.Height, bmp2.PixelFormat);

Das du wirklich ein valides Bild beim auslesen kommst, kannst du wie bestätigen? Hast du das mal in eine Picturebox gepackt um zu gucken ob das Bild korrekt ausgelesen wird? Ich geh nur alle Varianten durch was deine Exception auslesen könnte, daher die Fragen.
 
Ja, in der Ursprungsversion wurde das Bild direkt in die PB gepackt, von daher weiß ich, dass das Auslesen klappt.

Anscheinend lag es wirklich daran, dass ich den FileStream geschlossen habe, bevor ich geklont habe. Aber wieso ist das so? Ohne Klonen konnte ich auch einfach das Bild aus dem FS auslesen, den FS schließen und dann mit dem Bild arbeiten, wieso braucht das Klonen noch einen offenen FS?

Mein "unerklärlicher Fehler", der nun auftrat lag an der neuen verwendeten Palette. Da ich mit GetPixel(x, y).R im folgenden Arbeite gab es Ärger, denn irgendwie wünscht sich die Funktion anscheinend eine ARGB-Tabelle und keine reine RGB-Tabelle. Mit 32bppArgb als PixelFormat hat es nun funktioniert.

edit: Letztendlich wollte ich ja gerade nicht da PixelFormat von bmp2 übernehmen, da das Programm auch mit indizierten Bildern (zum Beispiel gif) umgehen können soll, aber ich kein Graphics-Objekt aus einem indizierten Bild herstellen kann. Deshalb die Umwandlung in eine nicht indizierte Tabelle.

Die kleine Nebenfrage aus dem Ausgangspost ist allerdings noch offen, da wüsste ich gerne, was sich eher anbietet.

edit: Irgendwie hat das jetzt nicht ganz so geklappt, wie ich mir das gedacht habe. Bei einer gif-Datei meckert der beim erstellen des Graphic-Objekts weiterhin wegen der indizierten Palette. Mein Code:
Code:
static Bitmap bmp, bmp2;
static Graphics Graphic;

...

bmp2 = new Bitmap(FS);
bmp = bmp2.Clone(new Rectangle(0, 0, bmp2.Width, bmp2.Height), PixelFormat.Format32bppArgb);
FS.Close();
bmp2.Dispose();
pbSchrift.Image = bmp;
Graphic = Graphics.FromImage(bmp);

edit: Ich habe mittlerweile einen Umweg um die ganze indizierte Geschichte gefunden, allerdings wüsste ich trotzdem gerne, wie man denn nun die Indizierung entfernen kann.
 
Zuletzt bearbeitet:
Zurück
Oben