Zapisywanie plików graficznych

0

Bawiłem się trochę filtrem medianowym, wyświetlany obraz (obiekt klasy Image) tworzę tak

MemoryImageSource mis=new MemoryImageSource(width,height,pixels,0,width);
Image img=createImage(mis); //createImage to metoda klasy JFrame odziedziczona z Component

Przykładowy wygląd ekranu: user image.
Do zapisywania przetworzonego obrazka używam

ImageIO.write(bi,format,file);

bi (klasa BufferedImage) jest tworzony w opisany tutaj http://www.exampledepot.com/egs/java.awt.image/Image2Buf.html sposób.
Efekty są takie:
format gif: user image
format png user image
format jpg user image
Co zmienić, żeby dało się dobrze zapisać w formacie jpg ?

0

odświeżam

0

Nie bardzo rozumiem, co jest problemem - czy to, że obrazek jest niewyraźny, czy to, że w ogóle się nie zapisuje? (o ile)
Natomiast podana przez Ciebie metoda rysowania obrazka na obrazku bufowowanym zawiera błędną moim zdaniem koncepcję. Chodzi o to, że uzależnia ona jakość obrazu od bieżącego trybu graficznego ekranu podczas gdy nie powinno to ze sobą mieć nic wspólnego. Format obrazka docelowego powinien zależeć wyłącznie od formatu obrazka źródłowego. Stąd użycie createCompatibleImage() jest po prostu paskudnym błędem. Gdyby ktoś chciał wykonać tę funkcję mając tymczasowo tryb graficzny mono (Black&White), to dostałby w efekcie obrazek monochromatyczny - coś co w ogóle nie powinno wystąpić.
Być może autor tej funkcji nie rozumiał zastosowania funkcji createCompatibleImage() i zasugerował się nazwą. Na dodatek kiedy system nie ma ekranu, to łapie wyjątek, który uniemożliwia wykonanie konwersji i go ignoruje, po czym kontynuuje resztę kodu, który nie ma już sensu.
Format graficzny ekranu nieczęsto odpowiada formatom plików graficznych. Na przykład dla ARGB (ale nie HDR) odpowiednim typem zapisu, który odpowiadałby buforowi ekranu byłby nieskompresowany typ Targa (TGA). Stąd jeżeli próbuje się zapisywać ramkę ekranu, to obrazek taki zwykle dostaje znacznik formatu użytkownika.

0

Problemem jest to, że plik zapisany w formacie jpg jest różny od tego co widać na ekranie,ponadto w każdej przeglądarce plików graficznych różni się od plików zapisanych w formacie gif oraz png.
Znasz jakąś prawidłową metodę zapisywania obiektów klasy Image do plików ?
BTW, z twoją krytyką metody w dużym stopniu się nie zgadzam - zapisując widziany na ekranie obraz oczekuję że jak sobie ten plik otworzę (potem, na innym komputerze), to zobaczę mniej więcej to samo. Ja też decyduję o formacie pliku, a nie format oryginalnego pliku graficznego.

0

bogdans, mój znajomy który robił tylko skalowanie biliniowe, zapisywał do jpg. Obraz różnił się diametralnie, np. inne kolory. W innych formatach nie było tego problemu. IMO Problem leży w formacie zapisu, w jpg pierwsze 8 bitów to kanał alfa o ile mnie pamięć nie myli.

0
bogdans napisał(a)

Problemem jest to, że plik zapisany w formacie jpg jest różny od tego co widać na ekranie,ponadto w każdej przeglądarce plików graficznych różni się od plików zapisanych w formacie gif oraz png.
Znasz jakąś prawidłową metodę zapisywania obiektów klasy Image do plików ?

O ile pamiętam, to była zamieszczona nawet tu na forum nie dalej jak pół roku temu (od takiego czasu tu jestem...).
Natomiast był to dość długi kod ponieważ java nie zawiera kodera JPEG, a tylko dekoder. Tak więc było tam dopasowywanie formatu, kwantyzacja, odrzucanie i parę innych rzeczy. Nie przyglądałem się temu zbytnio jednak bo robienie obsługi znanych formatów danych, to dla mnie raczej strata czasu. Jest conajmniej kilkanaście darmowych implementacji zarówno w C, C++ i ze dwie w Javie.

bogdans napisał(a)

BTW, z twoją krytyką metody w dużym stopniu się nie zgadzam - zapisując widziany na ekranie obraz oczekuję że jak sobie ten plik otworzę (potem, na innym komputerze), to zobaczę mniej więcej to samo.
Ja też decyduję o formacie pliku, a nie format oryginalnego pliku graficznego.

Założenie świetne i prawidłowe. Tyle, że nie takim sposobem. Używając tak zaimplementowanej metody o formacie pliku decydujesz nie ty, ale de facto system operacyjny. Jeżeli odpaliłbyś to jako RMI, to byłoby nawet gorzej - o formacie mógłby decydować zupełnie inny komputer, o którego ustawieniach nie miałbyś zasadniczo pojęcia.
Zapisywany obraz powinien bazować na informacjach pliku źródłowego z jednego powodu - tracisz najmniejsza ilość informacji. Poza tym co z grafiką o rozdzielczościach bardzo małych lub bardzo dużych? Takich, których umieszczanie w całości na ekranie nie ma najmniejszego sensu. Ba, co z obrazkami, których wielkość po rozpakowaniu jest tak duża, że pamięć obrazu współczesnych kart graficznych nie podoła? A przecież i takie pliki trzeba czasem obrabiać (np. mapy satelitarne). Bazowanie na danych wprost ze źródła (co nie oznacza na formacie) ma jeszcze większe znaczenie na formatach stratnych.
Na koniec - Wiązanie zapisywanego pliku obrazka z planami graficznymi konkretnego urządzenia wyświetlającego nie jest zbyt dobre. O formacie powinieneś decydować ty - tworząc pusty obraz o porządanych przez Ciebie cechach formatu, typie danych rastra, palety, alfa (i czego tam jeszcze) oraz drukując na nim obrazek, który chcesz skonwertować. Wtedy dopiero można go kompresować w formacie plikowym i zapisywać na dysk. W każdym razie tak to się robiło kiedyś w C.

0

@Olamagato, napisałem że bawię się filtrem medianowym, oznacza to między innymi, że program napisałem dla siebie i znajomych (nie jest profesjonalny, komercyjny,itd) i ma prawo działać źle na dużych, małych i różnych nietypowych obrazkach.
Rzuciłem okiem na wspomnianą przez Ciebie metodę http://www.koders.com/java/fid646C951F5C8FC602AFB2336581C6415368DE590A.aspx przerażający kod.
Znalazłem na forum inny sposób http://4programmers.net/Forum/420240?h=BufferedImage#id420240 prócz wspomnianych przez Ciebie wad ma on jedną dodatkową - korzysta z nieoficjalnego pakietu com.sun.image.codec.jpeg. Mi on na razie wystarczy.

0

zobacz też ten temat:

http://4programmers.net/Delphi/FAQ/Grafika/Jak_zrobi%C4%87_zrzut_ekranu_do_komponentu_TImage_

Jak zapisać rysunek, rysunki po formie do bitmapy, pliku ? patrz mój komentarz

1 użytkowników online, w tym zalogowanych: 0, gości: 1