Błędy przy wyświetlaniu obrazków

0

Piszę pewien program, który wyświetla obrazki BufferedImage. Samo wyświetlanie wykonuję w następujący sposób:

// TempView - obiekt BufferedImage zawierajacy obraz do wyswietlenia
// PictureView - JLabel polozony na formie

ImageIcon ImgView = null;
ImgView = new ImageIcon(TempView);
PictureView.setIcon(ImgView);
PictureView.repaint();

Dość często wyświetlanie jest błędne, ale zawsze błąd jest tylko przy wyświetlaniu, a wewnątrz programu jest wszystko prawidłowo.

W załączniku przykład wyświetlania z błędem. Jaka jest tego przyczyna i jak to poprawić?

Ten JLabel PictureView jest umieszczony w JScrollPane, a ten jest w JPanel.

Robienie Repaint dla tych elementów nie rozwiązuje problemu

0

a jak masz bufferedimage ustawiony ? Tam jest strasznie dużo typów do wyświetlania.

0

BufferedImage.TYPE_INT_BGR
BufferedImage.TYPE_3BYTE_BGR

Przy obu jest ten sam problem.

Często zmiana wymiarów okna powoduje zniknięcie błędu. Problem dotyczy wyłącznie wyświetlania, a operacje, jak pobranie koloru piksela, zapis do pliku przebiegają zawsze bezbłędnie.

0

Jeżeli chcesz uniknąć problemów z wyświetlaniem różnych obrazków z różnych źródeł, to używaj takich metod jak createCompatibleImage i createCompatibleVolatileImage. Dzięki temu możesz zawsze "przekleić" zawartość innego wczytanego obrazka za pomocą metody drawImage do tak utworzonego obrazka buforowanego. Ten musi zostać zawsze dobrze wyświetlony ponieważ ma plan identyczny z aktualnie używanym trybem graficznym. Poza tym tak zrobione obrazy są renderowane i buforowane z maksymalną możliwą szybkością jaka jest dostępna w Javie (praktycznie identyczną z programami natywnymi systemu).

0
Olamagato napisał(a)

Jeżeli chcesz uniknąć problemów z wyświetlaniem różnych obrazków z różnych źródeł, to używaj takich metod jak createCompatibleImage i createCompatibleVolatileImage. Dzięki temu możesz zawsze "przekleić" zawartość innego wczytanego obrazka za pomocą metody drawImage do tak utworzonego obrazka buforowanego. Ten musi zostać zawsze dobrze wyświetlony ponieważ ma plan identyczny z aktualnie używanym trybem graficznym. Poza tym tak zrobione obrazy są renderowane i buforowane z maksymalną możliwą szybkością jaka jest dostępna w Javie (praktycznie identyczną z programami natywnymi systemu).

Dzisiaj sprawdzałem i użycie tych metod nie pomaga.

Obraz wyswietlam w taki sposób:
Na formularzu jest jLabel o nazwie PictureView, a BufferedImage ma nazwę TempView.

ImageIcon ImgView = new ImageIcon(TempView);
PictureView.setIcon(ImgView);
PictureView.repaint();

Próbowałem jeszcze w taki sposób z panelem jPanel:

Graphics G = jPanel1.getGraphics();
Gr.drawImage(TempView, 0, 0, PW, PH, null);

Wtedy jest jeszcze gorzej, bo rysunek jest "nietrwały", zminimalizowanie lub zasłonięcie okna powoduje usunięcie rysunku.

Co więcej, testowałem działanie programu w MacOS i Linux (wirtualne maszyny), w tych systemach nie ma żadnych problemów.

Natomiast w Windows, jak wyłączę przyspieszenie karty graficznej (PPM na pulpicie, właściwości, ustawienia, zaawansowane, karta Rozwiązywanie problemów, suwak w lewo do końca), to problem znika. W programach pisanych w innych językach nie mam takich problemów.

0

Prawdopodobnie źle ich używasz. Trzeba dobrze wczytać się w dokumentację, żeby załapać jak tego używać. Możesz spróbować przetestować swój kod jeszcze raz używając metody Image.setAccelerationPriority() z argumentem 0f (bez akceleracji) oraz 1f (pełna akceleracja). Oczywiście jakieś 90% programów generujących grafikę w Javie w ogóle nie potrzebuje tej właściwości (moje zdanie).

A co do tematu (bo to wyżej to moim zdaniem sprawa poboczna), czy aby gdzieś w kodzie nie masz jakiegoś zagubionego drawImage, które wywołuje Ci się gdzieś z boku ze złymi współrzędnymi? Bo to byłoby najprostsze wytłumaczenie takiego efektu. Może to być również ponowne wywołanie tego samego drawImage wywołane przypadkiem jeszcze raz ze śmieciami zamiast właściwych argumentów.

0
Olamagato napisał(a)

Prawdopodobnie źle ich używasz. Trzeba dobrze wczytać się w dokumentację, żeby załapać jak tego używać. Możesz spróbować przetestować swój kod jeszcze raz używając metody Image.setAccelerationPriority() z argumentem 0f (bez akceleracji) oraz 1f (pełna akceleracja). Oczywiście jakieś 90% programów generujących grafikę w Javie w ogóle nie potrzebuje tej właściwości (moje zdanie).

Próbowałem czegoś takiego, przerabiając jeden przykład znaleziony w Google.

    GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice device = environment.getDefaultScreenDevice();
    GraphicsConfiguration config = device.getDefaultConfiguration();
    BufferedImage bufimage = config.createCompatibleImage(width, height, Transparency.OPAQUE);

I taki obraz próbowałem położyć na formie. Nic się nie zmieniło.

Przykłady wymnienione w poprzednim poście (jako ikona jLabela i rysowanie w jPanelu) to też były znalezione w Google.

Możesz podać przykład próby rozwiązania problemu? Głównie chodzi o wyświetlenie (osadzenie) obrazka BufferedImage na formularzu Swing.

Olamagato napisał(a)

A co do tematu (bo to wyżej to moim zdaniem sprawa poboczna), czy aby gdzieś w kodzie nie masz jakiegoś zagubionego drawImage, które wywołuje Ci się gdzieś z boku ze złymi współrzędnymi? Bo to byłoby najprostsze wytłumaczenie takiego efektu. Może to być również ponowne wywołanie tego samego drawImage wywołane przypadkiem jeszcze raz ze śmieciami zamiast właściwych argumentów.

Jeżeli chodzi o niesłuszne lub błędne użycie "drawimage" (który powoduje niekontrolowane i nieprawidłowe narysowanie obrazka, co objawia się opisywanym błędem), to nie ma takiej opcji z następujących powodów:

  • raz jest, raz nie ma, pewna losowość
  • obecność błedu zależna od warunków pracy programu (opisane w poprzednim poście)
  • akurat w tym przypadku jest tylko punkt (0,0), pisałem jeszcze 2 inne programy, w których ten sam błąd również występuje
  • ze zmianą rozmiaru okna nie jest związana żadna akcja
  • nawet jak obraz jest wyświetlony z błędem, to jak się zrobi na przykład zapisane go do pliku, to zapisuje się bezbłędnie

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