Pytanie Numery źródłowych pasm rastrowych i źródłowych komponentów przestrzeni kolorów nie są zgodne, gdy czytam obraz [duplikat]


To pytanie już zawiera odpowiedź:

Kiedy próbuję odczytać obraz za pomocą następującego kodu

myPicture = ImageIO.read(new File("./src/javaassignment1b/Deck/Ace_Diamond_1.jpg"));

Otrzymuję następujący błąd

 Numbers of source Raster bands and source color space components do not match

Na badania jest podobne pytanie i wydaje się, że jest to problem z moim obrazem JPEG (został przycięty z większego obrazu, który mógł spowodować błąd) i muszę obejść problem ze skalą szarości, ponieważ nie mam pojęcia, co to jest i jak go zaimplementować.

UWAGA : Najpierw próbowałem używać ImageIcon, aby dodać do JPanel, ale to nie mogło działać, więc znalazłem to rozwiązanie które prowadzą do mojego obecnego problemu. Właśnie zaczynam programować w Javie.

EDYTOWAĆ: Tu są połączyć do obrazów i robię aplikację Java

Potrzebuję alternatywy, aby dodać obraz do JPanel.


11
2018-04-20 11:04


pochodzenie


Czy możesz podać dokładny plik JPG, który próbujesz załadować? Czy można "proste", konkretne obejście problemu wystarczające tutaj, np. Ładowanie obrazu za pomocą dowolnego programu do przeglądania obrazów i zapisywanie go ponownie (a następnie, prawdopodobnie, w formacie, który można odczytać bez problemów)? - Marco13
@ Marco13 Gotowe !! - Computernerd


Odpowiedzi:


Na to pytanie już udzielono odpowiedzi: https://stackoverflow.com/a/18400559/1042999 i jest to bardzo eleganckie rozwiązanie problemu. Rozwiązanie obejmuje użycie wtyczki do ImageIO z zaimplementowaną obsługą wielu formatów, które nie są obsługiwane przez domyślną implementację ImageIo. Szczegóły na temat korzystania z wtyczki w zwykłych aplikacjach java i kontenerach serwletów można znaleźć: https://github.com/haraldk/TwelveMonkeys


5
2018-01-05 14:58



Zależność Maven: <dependency><groupId>com.twelvemonkeys.imageio</groupId><artifactId>imageio-jpeg</artifactId><version>3.3.1</version></dependency> - Edd


Otwórz obrazy za pomocą dowolnej przeglądarki / edytora obrazów i zapisz je w "standardowym" formacie

Zastanawiam się, w jaki sposób obrazy zostały stworzone w pierwszej kolejności. Domyślam się, że użyłeś jakiegoś fantazyjnego, wyrafinowanego programu do obróbki zdjęć do "przycinania", o którym wspomniałeś, i że ten program pozwala na przechowywanie obrazów w niektórych nietypowych formatach, i że zrobił (lub nie) modyfikował niektóre opcje, które mają były dostępne przy zapisywaniu obrazu, nie wiedząc, co dokładnie oznaczają te opcje (przepraszam, jeśli nie doceniam twojej znajomości formatów obrazu i przestrzeni kolorów tutaj ...).

Przyczyną problemu jest jednak to, że obrazy są przechowywane w dziwnej formie YPbPr lub YCbCr przestrzeń kolorów (nie udało mi się dokładnie tego wymyślić, ale domyślnie oba nie są obsługiwane w ImageIO).

Żadna z moich prób zastosowania standardu konwersje kolorów dla YPbPb-> RGB lub YCbCb-> RGB wydawało się odtwarzać dokładny oryginalne kolory, ale jak można zauważyć podczas przeglądania artykułów z Wikipedii: Dosyć akademicka para została wypuszczona w świat przestrzeni kolorów.

Znowu: zrobiłbym to silnie zalecamy otwieranie obrazów za pomocą dowolnej przeglądarki / edytora obrazów i zapisywanie ich w "standardowym" formacie. A najlepiej jako PNG, ponieważ JPG nie jest odpowiedni dla tego rodzaju obrazów. JPG jest bardziej przeznaczony do "naturalnych" obrazów, takich jak zdjęcia. W przypadku takich "sztucznych" obrazów kompresja musi być bardzo niska, aby uniknąć artefaktów.

Jednak ten program pokazuje obraz z prawie poprawne kolory, ale konwersja kolorów nadal wydaje się nie do końca poprawna.

import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class StrangeImageTest
{
    public static void main(String[] args) throws IOException
    {
        final BufferedImage image = readImage(new File("Ace_Diamond_1.jpg"));

        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame f = new JFrame();
                f.getContentPane().add(new JLabel(new ImageIcon(image)));
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }

    static BufferedImage readImage(File file) throws IOException
    {
        return readImage(new FileInputStream(file));
    }

    static BufferedImage readImage(InputStream stream) throws IOException
    {
        Iterator<ImageReader> imageReaders = 
            ImageIO.getImageReadersBySuffix("jpg");
        ImageReader imageReader = imageReaders.next();
        ImageInputStream iis = 
            ImageIO.createImageInputStream(stream);
        imageReader.setInput(iis, true, true);
        Raster raster = imageReader.readRaster(0, null);
        int w = raster.getWidth();
        int h = raster.getHeight();

        BufferedImage result = 
            new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        int rgb[] = new int[3];
        int pixel[] = new int[3];
        for (int x=0; x<w; x++)
        {
            for (int y=0; y<h; y++)
            {
                raster.getPixel(x, y, pixel);
                int Y = pixel[0];
                int CR = pixel[1];
                int CB = pixel[2];
                toRGB(Y, CB, CR, rgb);
                int r = rgb[0];
                int g = rgb[1];
                int b = rgb[2];
                int bgr = 
                    ((b & 0xFF) << 16) | 
                    ((g & 0xFF) <<  8) | 
                     (r & 0xFF);
                result.setRGB(x, y, bgr);
            }
        }
        return result;
    }

    // Based on http://www.equasys.de/colorconversion.html
    private static void toRGB(int y, int cb, int cr, int rgb[])
    {
        float Y = y / 255.0f;
        float Cb = (cb-128) / 255.0f;
        float Cr = (cr-128) / 255.0f;

        float R = Y + 1.4f * Cr;
        float G = Y -0.343f * Cb - 0.711f * Cr;
        float B = Y + 1.765f * Cb;

        R = Math.min(1.0f, Math.max(0.0f, R));
        G = Math.min(1.0f, Math.max(0.0f, G));
        B = Math.min(1.0f, Math.max(0.0f, B));

        int r = (int)(R * 255);
        int g = (int)(G * 255);
        int b = (int)(B * 255);

        rgb[0] = r;
        rgb[1] = g;
        rgb[2] = b;
    }
}

(Uwaga: może to być znacznie prostsze, dzięki ColorConvertOp przekształca się w przestrzeń kolorów RGB z przestrzeni kolorów użytej dla obrazu. Ale jak wspomniano powyżej, nie udało mi się rozgryźć który do zapisania obrazu użyto przestrzeni kolorów, a nawet gdybym to wiedział, należałoby stworzyć odpowiednią ColorSpace realizacja. Pierwsze wyniki wyszukiwania w sieci, takie jak YCbCrColorSpace.java, nie działa dla podanych obrazów wejściowych ...)


4
2018-04-20 16:56



MS Paint wydaje się wypluwać pliki, które mają ten problem, przynajmniej dla mnie. Jaka byłaby dobra bezpłatna aplikacja lub (nawet lepsza) strona internetowa do naprawy tego problemu? - ArtOfWarfare
@ArtOfWarfare Nie wiedziałem (i prawie się nie spodziewałem), że MS Paint może tworzyć takie pliki. (Połknięcie rantu na temat "Microsoft i standardów" tutaj). Odnośnie aplikacji: Zasadniczo każdy program powinien móc tworzyć "właściwe" pliki PNG, z czego jestem zadowolony irfanview.com , ale możesz wybrać ten, który ci się podoba, lub (jeśli nie interesują Cię potencjalne problemy dotyczące prywatności / praw autorskich), którekolwiek z wyników wyszukiwania w internecie dla czegoś takiego jak "internetowy konwerter png" ... - Marco13
Potrzebuję plików, aby pozostały jpegami - to wymaganie od klienta (zgadzam się, png byłby lepszy pod każdym względem, ale piszą kontrole, więc robię to, co mówią). W każdym razie znalazłem rozwiązanie - otworzyłem pliki w gimpie, a następnie wyeksportowałem jako plik jpeg z domyślnymi ustawieniami. - ArtOfWarfare