Mam pewne dane binarne, które chcę zapisać jako obraz. Kiedy próbuję zapisać obraz, zgłasza wyjątek, jeśli strumień pamięci użyty do utworzenia obrazu został zamknięty przed zapisaniem. Powodem, dla którego to robię, jest to, że dynamicznie tworzę obrazy i jako takie ... muszę użyć strumienia pamięci.
to jest kod:
[TestMethod]
public void TestMethod1()
{
// Grab the binary data.
byte[] data = File.ReadAllBytes("Chick.jpg");
// Read in the data but do not close, before using the stream.
Stream originalBinaryDataStream = new MemoryStream(data);
Bitmap image = new Bitmap(originalBinaryDataStream);
image.Save(@"c:\test.jpg");
originalBinaryDataStream.Dispose();
// Now lets use a nice dispose, etc...
Bitmap2 image2;
using (Stream originalBinaryDataStream2 = new MemoryStream(data))
{
image2 = new Bitmap(originalBinaryDataStream2);
}
image2.Save(@"C:\temp\pewpew.jpg"); // This throws the GDI+ exception.
}
Czy ktoś ma jakieś sugestie, jak mogę zapisać obraz przy zamkniętym strumieniu? Nie mogę liczyć na to, że programiści będą pamiętać o zamknięciu strumienia po zapisaniu obrazu. W rzeczywistości programista nie miałby ŻADNEGO POMYSŁU, że obraz został wygenerowany przy użyciu strumienia pamięci (ponieważ dzieje się to w innym kodzie, gdzie indziej).
Jestem bardzo zmieszany :(
using
bloku. Myślę, żeoriginalBinaryDataStream2
został automatycznie usunięty po zakończeniu użytkowania. A to spowodowałoby wyjątek.Odpowiedzi:
Ponieważ jest to MemoryStream, naprawdę nie musisz zamykać strumienia - nic złego się nie stanie, jeśli tego nie zrobisz, chociaż oczywiście dobrą praktyką jest pozbycie się wszystkiego, co jest jednorazowego użytku. (Zobacz to pytanie, aby uzyskać więcej informacji.)
Jednak powinieneś pozbyć się mapy bitowej - a to zamknie strumień. Zasadniczo, gdy już nadasz konstruktorowi Bitmap strumień, jest on „właścicielem” strumienia i nie powinieneś go zamykać. Jak mówią dokumenty tego konstruktora :
Nie mogę znaleźć żadnych dokumentów obiecujących zamknięcie strumienia, gdy usuniesz bitmapę, ale powinieneś być w stanie to dość łatwo zweryfikować.
źródło
Wystąpił ogólny błąd w GDI +. Może również wynikać z nieprawidłowej ścieżki zapisu ! Zajęło mi to pół dnia, zanim to zauważyłem. Dlatego upewnij się, że dwukrotnie sprawdziłeś ścieżkę, aby zapisać obraz.
źródło
C\Users\mason\Desktop\pic.png
. Brak dwukropka! Spędziłbym wieczność, zanim to zauważyłem.Być może warto wspomnieć, że jeśli katalog C: \ Temp nie istnieje, zgłosi również ten wyjątek, nawet jeśli Twój strumień nadal istnieje.
źródło
Miałem ten sam problem, ale w rzeczywistości przyczyną było to, że aplikacja nie miała uprawnień do zapisywania plików na C. Kiedy zmieniłem na "D: \ .." obraz został zapisany.
źródło
Skopiuj plik Bitmap. Musisz pozostawić otwarty strumień przez cały okres istnienia mapy bitowej.
Podczas rysowania obrazu: System.Runtime.InteropServices.ExternalException: Wystąpił ogólny błąd w GDI
źródło
RawFormat
ma znaczenie. Jeśli chcesz tego użyć, pobierz go z obiektu gdzieś po drodze, ale ogólnie zapisz jako dowolny typ, który chcesz mieć .Możesz spróbować utworzyć kolejną kopię mapy bitowej:
źródło
Ten błąd pojawił się podczas próby z Citrix. Folder obrazów został ustawiony na C: \ na serwerze, do którego nie mam uprawnień. Po przeniesieniu folderu obrazów na dysk współdzielony błąd zniknął.
źródło
Wystąpił ogólny błąd w GDI +. Może się to zdarzyć z powodu problemów ze ścieżkami przechowywania obrazu. Otrzymałem ten błąd, ponieważ moja ścieżka przechowywania jest zbyt długa. Naprawiłem to, najpierw przechowując obraz w najkrótszej ścieżce i przenosząc go do właściwej lokalizacji za pomocą technik obsługi długich ścieżek.
źródło
Pojawił się ten błąd, ponieważ wykonywany przeze mnie automatyczny test próbował zapisać migawki w folderze, który nie istniał. Po utworzeniu folderu błąd został rozwiązany
źródło
Dziwne rozwiązanie, które sprawiło, że mój kod działał. Otwórz obraz w farbie i zapisz go jako nowy plik w tym samym formacie (.jpg). Teraz spróbuj z tym nowym plikiem i działa. Wyraźnie wyjaśnia, że plik może być w jakiś sposób uszkodzony. Może to pomóc tylko wtedy, gdy twój kod ma naprawione wszystkie inne błędy
źródło
Pojawił się również u mnie, gdy próbowałem zapisać obraz na ścieżce
C:\Program Files (x86)\some_directory
i
.exe
nie został uruchomiony jako administrator, mam nadzieję, że może to pomóc komuś, kto ma ten sam problem.źródło
Dla mnie poniższy kod zawiesił
A generic error occurred in GDI+
się w linii, która zapisuje do plikuMemoryStream
. Kod działał na serwerze internetowym i rozwiązałem go, zatrzymując i uruchamiając pulę aplikacji, na której działała witryna.To musiał być jakiś wewnętrzny błąd w GDI +
źródło
Natknąłem się na ten błąd, gdy próbowałem prostej edycji obrazu w aplikacji WPF.
Ustawienie źródła elementu obrazu na mapę bitową zapobiega zapisywaniu pliku. Nawet ustawienie Source = null nie wydaje się zwolnić pliku.
Teraz po prostu nigdy nie używam obrazu jako elementu źródła obrazu, więc mogę nadpisać po edycji!
EDYTOWAĆ
Po zapoznaniu się z właściwością CacheOption (podziękowania dla @Nyerguds) znalazłem rozwiązanie: Zamiast więc używać konstruktora Bitmap, muszę ustawić Uri po ustawieniu
CacheOption
BitmapCacheOption.OnLoad
. (Image1
PoniżejImage
element Wpf )Zamiast
Posługiwać się:
Zobacz to: Buforowanie obrazów WPF
źródło
BitmapCacheOption.OnLoad
aby odłączyć je od źródła ładowania.Wypróbuj ten kod:
źródło
Użyłem procesora obrazu do zmiany rozmiaru obrazów i pewnego dnia otrzymałem wyjątek „Wystąpił ogólny błąd w GDI +”.
Po chwili odszukania próbowałem ponownie wykorzystać pulę aplikacji i bingo działa. Więc zapisuję to tutaj, mam nadzieję, że pomoże;)
Twoje zdrowie
źródło