2011-01-27 10 views
18

Pracuję nad aplikacją do przetwarzania obrazu dla systemu Android, która rozpoznaje notację muzyczną ze zdjęć wykonanych na arkuszach muzycznych.Czy możliwe jest pocięcie mapy bitowej na małe kawałki bez załadowania całej rzeczy do pamięci?

Próbowałem załadować cały obraz do bitmapy przy użyciu metody BitmapFactory.decodeFile(imgPath), ale ponieważ mój telefon nie ma wystarczającej ilości pamięci, otrzymuję komunikat o "wielkości sterty maszyny wirtualnej". Aby obejść to, chciałbym posiekać cały obraz na mniejsze kawałki, ale nie jestem pewien, jak to zrobić.

Widziałem też, że to możliwe, aby zmniejszyć rozmiar pamięci bitmapy za pomocą inSampleSize property klasy BitmapFactory.Option, ale jeśli to zrobię, że nie dostanie wysokiej rozdzielczości obrazu potrzebne do notacji muzycznej proces rozpoznawania.

Czy mimo to można to zrobić bez przechodzenia do NDK?

+0

naprawdę jest to plik zakodowany w postaci bitmapy? Czy możesz skompresować obraz źródłowy, aby nie był tak duży? Dla samej muzyki nie powinno być wielu kolorów ... Jak duże są bajty i rozdzielczość, z którymi pracujesz? – Matt

+0

Czy mapa bitowa jest twoja czy użytkownika? Jeśli tak, rozważ przechowywanie wstępnie rozdrobnionego i/lub w mniejszej ilości kolorów. Jeśli to użytkownik, czy jest to przypadek graniczny, czy typowy sygnał wejściowy? Jeśli jest to granica, zastosuj sprawdzanie poprawności/pełną obsługę błędów. Jeśli typowe, rozważ ponownie swój wybór platformy. –

+0

Bitmapa pochodzi od użytkownika. Wykona zdjęcie z kamery mobilnej. Muszę wykorzystać jak największą bitmapę, ponieważ w procesie rozpoznawania skuteczność wynika z tego. Dziękuję za edycję i przepraszam za mój słaby angielski. – OffCS

Odpowiedz

1

Jeśli pochodzi z aparatu fotograficznego, obraz będzie prawdopodobnie w formacie jpeg. Możesz użyć zewnętrznej biblioteki jpeg - albo w java, albo poprzez NDK, cokolwiek możesz znaleźć - aby dać ci lepszą kontrolę i załadować kawałek na raz. Jeśli potrzebujesz go jako android.graphics.Bitmap, podejrzewam, że będziesz musiał ponownie kodować obraz jako obraz PNG lub JPEG i przekazać go do BitmapFactory.decodeByteArray(). (Jeśli problem dotyczy pamięci, pamiętaj, aby szybko zapomnieć odwołań do fragmentów mapy bitowej, aby moduł do zbierania śmieci działał efektywnie.)

Ta sama technika będzie działać, jeśli grafika wejściowa ma format PNG, lub prawie wszystko, co jest pod warunkiem, że możesz znaleźć dla niego odpowiedni kod dekodowania.

Uważam, że ładując obraz kawałek, stajesz się algorytmicznym wyzwaniem, decydując, które części tego przedmiotu są naprawdę interesujące. Zauważyłem, że BitmapFactory.Options zawiera opcję podpróbkowania, która może być przydatna, jeśli chcesz przeanalizować podgląd obrazu, aby zdecydować, które regiony załadować w pełnym zakresie.

1

Jeśli masz do czynienia ze zdjęciami JPEG, zobacz moją odpowiedź na this question oraz this example.

Nie wiem, jak to możliwe, aby uzyskać libijg na Androida, ale jeśli tak, to jest warte strzału.

27

Android 2.3.3 ma nowy interfejs API o nazwie android.graphics.BitmapRegionDecoder, który umożliwia wykonanie dokładnie tego, co chcesz.

Można by na przykład wykonać następujące czynności:

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false); 
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null); 

Łatwe :)

+0

Ta klasa jest w wersji 2.3.3 i jest w porządku, jeśli wszystko jest w porządku, ponieważ Twoja aplikacja działa tylko w wersji 2.3. .3 i więcej, ale co z poprzednimi wersjami? –

+3

Możesz pobrać kod z repozytorium git i użyć go w swojej aplikacji :) –

+0

@RomainGuy, czy mógłbyś trochę wyjaśnić, jak to zrobić? Wygląda na to, że kod odwołuje się do natywnych metod. Czy musimy też pobrać te natywne metody z git i skompilować je z NDK, czy też klasa java jest wystarczająca? – snapfractalpop

Powiązane problemy