Warsztat - Programowanie gier

Lipiec 30, 2010, 17:34:37 *
Witamy, Gość. Zaloguj się, lub zarejestruj proszę.

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności: Warsztat, Regulamin forum, #warsztat, Wiki, FAQ, NoPaste, Mapa
 
   Strona główna   Pomoc Szukaj Zaloguj się Rejestracja  
Strony: [1]
  Drukuj  
Autor Wątek: Wczytywanie obraz do Tablicy byte[] //[J2ME]  (Przeczytany 940 razy)
Adam B
Full Member
***

wiadomości: 103


Zobacz profil
« : Czerwiec 16, 2009, 18:56:54 »

Witam,
Chciałem upiększyć mój jar i w związku z tym zabrałem się za pakowanie plików PNG do jednego binarnego (to teoretycznie może też przyśpieszyć wczytywanie, jednak nie o to mi chodzi). Pokombinowałem i wymyśliłem coś takiego (kod jest eksperymentalny więc i brzydki):

Kod:
int x=0;
int y=0;

// ŻEBY ZOBACZYĆ ILE WCZYTUJE ZNAKÓW
try{
    InputStreamReader in = new InputStreamReader(getClass().getResourceAsStream("/x.png"));
            while ((in.read())!=-1) {
                x++;
            }
}catch(IOException ioe){
    System.out.println("ale gdzie plik?");
    ioe.printStackTrace();
}

// TABLICA Z BYTAMI :)
byte tab[] = new byte[x]; // Tablica dokładnie jakiej potrzeba ;)

try{
    InputStreamReader in = new InputStreamReader(getClass().getResourceAsStream("/x.png"));
            int cos=0;
            while ((cos = in.read())!=-1) {
                tab[y]=(byte)cos; // Wpisanie do tablicy kolorku
                y++;
            }
}catch(IOException ioe){
    System.out.println("ale gdzie plik?");
    ioe.printStackTrace();
}
       
        Image img;
        img = Image.createImage(tab, 0, x);  // Tutaj pojawia się błąd związany ze złym argumentem - dwoje się i troje i nic nie umiem wymyślić :/
        g.drawImage(img, 50, 50, 0);

Teoretycznie wszytko jest ok ale emulator mi się burzy !
Pozdrawiam Smiley
Zapisane
grrr
Full Member
***

wiadomości: 177


Zobacz profil
« Odpowiedz #1 : Czerwiec 17, 2009, 09:57:08 »

Wiesz, jak zawsze... Zdania typu: "tutaj pojawia się błąd związany ze złym argumentem" i "emulator mi się burzy" prawdopodobnie nic nikomu nie powiedzą, więc i ciężko będzie pomóc.
Zapisane
Adam B
Full Member
***

wiadomości: 103


Zobacz profil
« Odpowiedz #2 : Czerwiec 17, 2009, 10:11:39 »

Wiesz, jak zawsze... Zdania typu: "tutaj pojawia się błąd związany ze złym argumentem" i "emulator mi się burzy" prawdopodobnie nic nikomu nie powiedzą, więc i ciężko będzie pomóc.

Nie z kodu wynika wszystko co i jak. Jak ktoś kiedyś robił wczytywanie png w podobny sposób to wie na czym polega problem.

Wymaga jest tablica typu byte (do funkcji tworzącej Image), a problem polega na tym ze InsputStreamReader.read zwraca int - nie ma innej metody tej klasy żeby zwracała co innego i to jest chyba jedyna opcja odczytu zawartości JARa. Natomiast pierwsza liczba odczytana z pliku PNG to 8200 czy jakoś tak - także znacznie wykracza po za zakres byte:/ Dlatego dane wejściowe są złe i nie mam pojęcia jak rozwiązać ten problem. Na pewno da się to jakoś zrobić bo w wielu gra widziałem, że był ogólny plik binarny zawierający wszystkie grafiki z gry+miejsce ich położenia + grafike czcionki + teksty...

//EDIT: pobawie się może dataInputStream - może to coś pomoże..
« Ostatnia zmiana: Czerwiec 17, 2009, 10:22:11 wysłane przez Adam B » Zapisane
MadMax
Full Member
***

wiadomości: 153


Zobacz profil
« Odpowiedz #3 : Czerwiec 17, 2009, 10:34:00 »

Witam

to nie lepiej pakowac do binarki szerokosc, wysokosc kazdego obrazka, indeksy kolorow, oraz oddzielna wspolna dla obrazkow palete jako dodatkowy plik, lub na poczatku binarki ?.

Nie wiem czy programisci wrzucaja do binarnego pliku obrazki w formacie png - to wydaje mi sie ze tak powiem malo optymalne.

btw. jesli chcesz wczytac np. liczbe typu int, to najprosciej bajty przerzucic:

Kod:
int len = (is.read() & 0xFF) << 24;
 len |= (is.read() & 0xFF) << 16;
 len |= (is.read() & 0xFF) << 8;
 len |= (is.read() & 0xFF);

Jesli masz np. w danej pozycji pliku naglowek o rozmiarze obrazka, to (klasyczna) bezpieczna i szybsza wersja funkcji wczytujacej wyglada tak :

Kod:
    public final byte[] loadFile(String f, int apos) {
        byte buffer[], tmp[];

        int len, p = 0;

        try {
            InputStream is = _class.getResourceAsStream(f);
            if (is == null) {
                throw new Exception("File Does Not Exist");
            }

            if (apos > 0) {
                is.skip(apos);
            }

            len = (is.read() & 0xFF) << 24;
            len |= (is.read() & 0xFF) << 16;
            len |= (is.read() & 0xFF) << 8;
            len |= (is.read() & 0xFF);
            buffer = new byte[len];
            tmp = new byte[len];

            while ((len = is.read(tmp, 0, tmp.length)) > 0) {
                System.arraycopy(tmp, 0, buffer, p, len);
                p += len;
                if (p >= buffer.length) {
                    break;
                }
            }
            tmp = null;
            is.close();
            is = null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            buffer = null;
            tmp = null;
        }
        return buffer;
    }

mozna to zoptymalizowac, ale nevermind Smiley.

Pozdrawiam,
madmax
Zapisane
grrr
Full Member
***

wiadomości: 177


Zobacz profil
« Odpowiedz #4 : Czerwiec 17, 2009, 10:48:51 »

InputStrem udostępnia metodę read(byte[]), wystarczy połączyć to z ByteArrayOutputStream - wtedy nie musisz wiedzieć, jaki długi jest plik, czytasz z inputStream i piszesz to ByteArrayOutputStream (póki inputStream wciąż coś zwraca), a potem robisz toByteArray()  - piszę z głowy. Ani nie musisz modyfikować pliku, ani wczytywać go dwukrotnie.
Zapisane
Adam B
Full Member
***

wiadomości: 103


Zobacz profil
« Odpowiedz #5 : Czerwiec 17, 2009, 10:58:29 »

Żeby z wysokości, szerokości, palety i indeksu odczytać obrazki trzeba użyć CreateRGBImagen pomysł dobry i łatwy Wink Tylko jedynym problem jest stworzenie narzędzia, które będzie taki plik tworzyło ale to też jest kilka godz. roboty. Mi natomiast chodziło o coś troszke innego:

Oto rozwiązanie tego co chciałem osiągnąć.
Kod:
int x=155;  // WIEM ZE OBRAZEK MA 155 BAJTÓW
byte tab[] = new byte[x];

try{
    DataInputStream in = new DataInputStream(getClass().getResourceAsStream("/x.png"));
    while ((in.read(tab, 0, x))!=-1) {}
}catch(IOException ioe){}

        Image img;
        img = Image.createImage(tab, 0, x); //  elegancko się tworzy obrazek.
        g.drawImage(img, 50, 50, 0);


Podejrzewam, że tworząc swój format to i tak skorzystam z createRGBImage. Ze względu na większą prostote wykonania.
Zapisane
Strony: [1]
  Drukuj  
 
Skocz do:  

Hosting: Polska Strefa - Ogłoszenia
Powered by SMF 1.1.7 | SMF © 2006, Simple Machines LLC