2016-04-25 10 views
6

Pracuję nad aplikacją, która wymaga wielu porównań danych obrazu w JavaFX. Aby to porównać, muszę uzyskać dane rgb pikseli w obrazach. Załóżmy, że zdjęcie, które muszę porównać, to Picture1 i Picture2. Picture1 to zdjęcie wejściowe wybrane przez użytkownika. Picture2 to rysunek, który robię programowo.Alternatywa (ów) konwersji Canvas to WritableImage

AFAIK, jedynym sposobem uzyskania danych rgb na piksel w JavaFX jest PixelReader z Image. To jest w porządku dla Picture1, ponieważ jest to wejście. Ale muszę zrobić rysunek na Picture2 i Picture2 jest Canvas (rysuję wielokątów na Picture2 i dlatego rysowanie piksel po pikselu z PixelWriter jest nieco skomplikowane IMO) i nie posiada PixelReader lub coś o podobnej funkcjonalności . Więc moje rozwiązanie jest w następujący sposób:

  1. Czytaj obrazu wejściowego i uczynić Picture1
  2. Zrób płótnie i zrobić rysunek
  3. Attach płótna do sceny
  4. Zrobić migawkę sceny i zrobić WritableImage (picture2)
  5. Porównaj Picture1 i picture2

Więc mam metodę z czymś takim:

public static WritableImage makeDrawableImage(Canvas in) { 
    AnchorPane root = new AnchorPane(in); 
    WritableImage out = new WritableImage((int)in.getWidth(), (int)in.getHeight()); 
    Scene sc = new Scene(root, in.getWidth(), in.getHeight()); 

    out = in.snapshot(null, null); 

    return out; 
} 

Ukończenie migawki zajmuje bardzo dużo czasu. Wartość out nigdy nie zostanie przypisana. Nie wiem, co zrobiłem źle.

Czy jest jakaś alternatywa dla konwersji Canvas na Image lub WritableImage? A może jest biblioteka do łatwiejszego rysowania wielokątów z PixelWriter?

Proszę bądź łagodny dla mnie. To jest moje pierwsze pytanie na Stack Overflow i nie jestem programistą rzeczywistym ani studentem IT. Koduję jako hobby.

Dziękuję z góry. Twoje zdrowie.

Odpowiedz

1

Można utworzyć migawkę płótnie z tą metodą:

public static WritableImage pixelScaleAwareCanvasSnapshot(Canvas canvas, double pixelScale) { 
    WritableImage writableImage = new WritableImage((int)Math.rint(pixelScale*canvas.getWidth()), (int)Math.rint(pixelScale*canvas.getHeight())); 
    SnapshotParameters spa = new SnapshotParameters(); 
    spa.setTransform(Transform.scale(pixelScale, pixelScale)); 
    return canvas.snapshot(spa, writableImage);  
} 

Skala pikseli normalnie wynosi 1,0, chyba że masz ekran HiDPI.

+0

To nadal nie działa :(Mój problem dotyczy "out = in.snapshot" (null, null); "Zajmuje naprawdę dużo czasu ... Czy zrobienie zrzutu trwa tak długo? –

+0

t jak duże są twoje obrazy? – mipa

+0

Oczywiście nadal używasz swojego kodu, a nie mojego W moim kodzie nie ma linii 'out = in.snapshot (null, null);' Robienie migawki płótna o wymiarach 2000x2000 zajmuje tylko milisekundy: – mipa