Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для мобильных телефонов > Android

Android Разработка игр на платформе Android

Ответ
 
Опции темы
Старый 02.11.2013, 14:02   #1
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
загрузка картинки из архива сразу в Drawable

вопрос возник как всегда на ровном месте. понадобилось прочесть из zip-архива, что входит в apk (т.е. в проекте лежит в папке assets), файл. не распаковывать весь архив или файлы на диск/флешку (вдруг там места нет), а именно прочитать файл в поток и сразу закинуть его в Drawable для использования как фона кнопки, обоев и пр. (впрочем, там будут и файлы других форматов)

вот пример того, как я рылся в архивах до этого печального момента:
/* zipfilename - имя файла архива, filename - файл, который нужно найти в архиве *
     * unzipfilename - имя (и путь) файла, в который будет распакован файл filename  */
    
public static void zipExtract(String zipfilenameString filenameString unzipfilename) {
        try {
            
// буфер для чтения из архива
            
byte[] buf = new byte[1024];
            
// поток архива
            
ZipInputStream zipinputstream null;
            
// вхождения в архив
            
ZipEntry zipentry;
            
// создаем поток архива, параметр - свежесозданный поток файла архива
            
zipinputstream = new ZipInputStream(
                new 
FileInputStream(zipfilename));
            
// получаем очередное вхождение в архив
            
zipentry zipinputstream.getNextEntry();
            
// пока все вхождения в архив не кончатся
            
while (zipentry != null) { 
                
// получаем имя вхождения (запакованного файла или папки)
                
String entryName zipentry.getName();
                if (
entryName == filename) {
                    
// количество фактически прочитанных байтов
                    
int n;
                    
// поток для записи распакованного файла/папки
                    
FileOutputStream fileoutputstream;
                    
// открываем файл вхождения (файла/папки)
                    
File newFile = new File(entryName);
                    
// если очередное вхождение - папка, то пропускаем текущую итерацию цикла
                    
String directory newFile.getParent();
                    if(
directory == null) {
                        if(
newFile.isDirectory())
                            break;
                    }
                    
// если вхождение - файл, то создаем выходной поток для записи распакованного файла
                    
fileoutputstream = new FileOutputStream(filename);
                    
// переписываем весь файл из архива в созданный поток
                    
while ((zipinputstream.read(buf01024)) > -1)
                        
fileoutputstream.write(buf0n);
                    
// закрываем поток
                    
fileoutputstream.close();
                    
// закрываем вхождение
                    
zipinputstream.closeEntry();
                    
// получаем следующее вхождение
                    
zipentry zipinputstream.getNextEntry();
                }
            }
            
// закрываем поток архива
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
    } 
самому странно, что такую простую, вроде бы, вещь как извлечение файла из архива сразу в картинку не удается реализовать без необходимости распаковывать данные сначала в файлы(((
говорю сразу - мануалами уже обчитался. какаю кодом, блюю газетой. так что просьба ответить тем, у кого есть идеи по теме, а не советы типа "кури мануалы".

заранее благодарен.
__________________
to be or not to be - it's not a question!
2b or not 2b = ff

Последний раз редактировалось barsunduk, 02.11.2013 в 22:15.
(Offline)
 
Ответить с цитированием
Старый 03.11.2013, 14:22   #2
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

с текстовым файлом проще, конечно.
а вот что с картинками и музыкой делать прямо не знаю. ((( как bytearray превратить в картинку типа png (с alpha) или jpg?

/* zipfilename - имя файла архива, filename - файл, который нужно найти в архиве *
     * на выходе - массив байтов, содержащая извлеченный файл  */
    
public static byte[] zipExtract(String zipfilenameString filename) {
        
// буфер для строки
        
byte[] buf null;
        try {
            
// поток архива
            
ZipInputStream zipinputstream null;
            
// вхождения в архив
            
ZipEntry zipentry;
            
// создаем поток архива, параметр - свежесозданный поток файла архива
            
zipinputstream = new ZipInputStream(new FileInputStream(zipfilename));
            
// получаем очередное вхождение в архив
            
zipentry zipinputstream.getNextEntry();
            
// пока все вхождения в архив не кончатся
            
while (zipentry != null) { 
                
// получаем имя вхождения (запакованного файла или папки)
                
String entryName zipentry.getName();
                
// если это искомый файл
                
if (entryName == filename) {
                    
// получаем размер найденного файла
                    
int entrysize = (int)zipentry.getSize();
                    
// создаем буфер для чтения из архива
                    
buf = new byte[entrysize];
                    
// читаем найденный файл из архива в буфер
                    
zipinputstream.read(buf0entrysize);
                    
// закрываем вхождение
                    
zipinputstream.closeEntry();
                    
// заканчиваем поиск
                    
break;
                }
                
// получаем очередное вхождение в архив
                
zipentry zipinputstream.getNextEntry();
            }
            
// закрываем поток архива
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
        
// возвращаем буфер
        
return buf;
    }
    
    
/* zipfilename - имя файла архива, filename - файл, который нужно найти в архиве *
     * на выходе - строка, содержащая извлеченный файл  */
    
public static String zipExtractTextfile(String zipfilenameString filename) {
        return 
zipExtract(zipfilenamefilename).toString();
    } 
__________________
to be or not to be - it's not a question!
2b or not 2b = ff
(Offline)
 
Ответить с цитированием
Старый 03.11.2013, 23:49   #3
Romanzes
Разработчик
 
Аватар для Romanzes
 
Регистрация: 06.04.2008
Сообщений: 541
Написано 196 полезных сообщений
(для 637 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

Есть замечательный класс BitmapFactory
В нем есть методы для получения Bitmap и из массива, и из файла, и даже из InputStream.
Из Bitmap легким движением руки получаем Drawable:
Drawable drawable = new BitmapDrawable(context.getResources(), bitmap);
Кстати, в случае InputStream не обязательно даже вспоминать про BitmapFactory, есть конструктор BitmapDrawable, принимающий в себя InputStream.
Читаешь файлы из zip-архива на первый взгляд правильно. Только вторую твою функцию можно будет уменьшить, учитывая, что не обязательно считывать картинку в массив байтов, а достаточно использовать InputStream.
А вообще, по поводу использования zip-архивов в качестве ассетов - я бы посоветовал перестать наркоманить и больше так не делать. Ты не забыл, что apk-файл - это тоже zip-архив?
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
barsunduk (04.11.2013)
Старый 04.11.2013, 13:14   #4
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

Сообщение от Romanzes Посмотреть сообщение
Ты не забыл, что apk-файл - это тоже zip-архив?
просто где-то когда-то читал, что папка assets не сжимается, в ней всё остается как есть. отложилось в голове, хотя чушь явная.
но это не основная причина. просто хотел редактор и интерпретатор собрать - подсовываешь программе один архив, а внутри и контент и интерфейс...
а вариант с InputStream и BitmapDrawable я уже пробовал, он не пошел. видимо, там был мой косяк. вернусь к нему и буду искать дыры. спасибо!

до смешного дошло. вот этот изврат (нерабочий, ессно):
public Drawable zipExtractImage(String zipfilenameString filename) {
        
Drawable img null;
        try {
            
ZipInputStream zipinputstream = new ZipInputStream(this.getAssets().open(zipfilename));
            
ZipEntry zipentry zipinputstream.getNextEntry();
            while (
zipentry != null) {
                
String entryName zipentry.getName();
                if (
entryName == filename) {
                    
img Drawable.createFromStream(zipinputstreamnull);
                    break;
                }
                
zipentry zipinputstream.getNextEntry();
            }
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
        return 
img;
    } 
__________________
to be or not to be - it's not a question!
2b or not 2b = ff

Последний раз редактировалось barsunduk, 08.11.2013 в 21:58.
(Offline)
 
Ответить с цитированием
Старый 15.11.2013, 01:41   #5
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

...
__________________
to be or not to be - it's not a question!
2b or not 2b = ff
(Offline)
 
Ответить с цитированием
Старый 15.11.2013, 01:57   #6
Romanzes
Разработчик
 
Аватар для Romanzes
 
Регистрация: 06.04.2008
Сообщений: 541
Написано 196 полезных сообщений
(для 637 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

Передай свой ZipInputStream в функцию BitmapFactory.decodeStream(InputStream is). Если ты в данный момент находишься на нужной тебе ZipEntry (ты переключаешься между ними с помощью getNextEntry()), то этот ZipInputStream выдаст только твою картинку, а не весь файл.
(Offline)
 
Ответить с цитированием
Старый 15.11.2013, 03:05   #7
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

я это уже пытался делать. только сейчас понял, почему не работало. с контекстами напутано было.
короче, вот РАБОЧИЙ ВАРИАНТ:
package ru.tururu.turu;

import java.io.*;
import java.util.zip.*;

import android.content.Context;
import android.graphics.drawable.Drawable;

public class  
Unzip {

    
// тут другие функции будут
    // ...

   /* Чтение картинки из архива в Assets. Пример вызова из Activity:
    * imageview1.setImageDrawable(Unzip.zipAssetsDrawable(
    * "image1.jpg", getApplicationContext()));
    * в папке Assets открывается архив assets.zip и из него извлекается
    * картинка filename сразу в Drawable */
    
public static Drawable zipAssetsDrawable(String filenameContext context) {
        
Drawable d null;
        
String zipfilename "assets.zip";
        try {
            
InputStream is context.getAssets().open(zipfilename);
            
ZipInputStream zipinputstream = new ZipInputStream(is);
            
ZipEntry zipentry zipinputstream.getNextEntry();
            while (
zipentry != null) { 
                
String entryName zipentry.getName();
                if (
entryName.equalsIgnoreCase(filename)) {
                    
Drawable.createFromStream(zipinputstreamentryName);
                    
zipinputstream.closeEntry();
                }
                
zipentry zipinputstream.getNextEntry();
            }
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
        return 
d;
    }

   
/*  чтение картинки из архива на диске
    *  в zipfilename - путь и имя архива, в filename - имя искомого файла
    *  пример вызова из Assets:
    *  imageview1.setImageDrawable(Unzip.zipFileDrawable(
    * "/mnt/sdcard/Android/data/TestProject/archive.zip", "image1.jpg"); */
    
public static Drawable zipFileDrawable(String zipfilenameString filename) {
        
Drawable d null;
        try {
        
FileInputStream is = new FileInputStream(zipfilename);
            
ZipInputStream zipinputstream = new ZipInputStream(is);
            
ZipEntry zipentry zipinputstream.getNextEntry();
            while (
zipentry != null) { 
                
String entryName zipentry.getName();
                if (
entryName.equalsIgnoreCase(filename)) {
                    
Drawable.createFromStream(zipinputstreamentryName);
                    
zipinputstream.closeEntry();
                }
                
zipentry zipinputstream.getNextEntry();
            }
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
        return 
d;
    }
    

всё, теперь можно делать редактор ресурсов под виндой, а результат сохранять в виде архива, который закидывается в ассетс или на флешку
__________________
to be or not to be - it's not a question!
2b or not 2b = ff

Последний раз редактировалось barsunduk, 15.11.2013 в 15:31.
(Offline)
 
Ответить с цитированием
Старый 15.11.2013, 13:29   #8
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

назначение класса - доставать ресурсы напрямую из архива, который лежит в папке assets приложения, либо где-то на устройстве или флешке. ресурсы ( пока только графика и строки в UTF-8 ) помещаются сразу в контейнеры. собственно, как это сделать, я и хотел спросить, когда создавал тему.

package ru.turururu.turu;

import java.io.*;
import java.util.zip.*;

import android.content.Context;
import android.graphics.drawable.Drawable;

public class  
Unzip {
    
    
// у меня всегда в ассетс будет только 1 архив с данными, из которого нужно доставать ресурсы
    
public static String zipfilename "data.zip";
    
    public static 
String StreamToString(InputStream is) {
        try {
            return new 
java.util.Scanner(is).useDelimiter("\\A").next();
        } catch (
java.util.NoSuchElementException e) {
            return 
"";
        }
    }
    
    
/* чтение строки из архива в Assets
     * пример вызова из Activity:
     * textview1.setText(Unzip.zipAssetsDrawable("text1.txt", getApplicationContext()));*/
    
public static String zipAssString(String filenameContext context) {
        
String s "";
        try {
            
ZipInputStream zipinputstream = new ZipInputStream(context.getAssets().open(zipfilename));
            
ZipEntry zipentry zipinputstream.getNextEntry();
            while (
zipentry != null) {
                if (
filename.equalsIgnoreCase(zipentry.getName())) {
                    
StreamToString(zipinputstream);
                    
zipinputstream.closeEntry();
                }
                
zipentry zipinputstream.getNextEntry();
            }
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
        return 
s;
    }

    
/* чтение строки из архива на диске
     * пример вызова из Activity:
     * textview1.setText(Unzip.zipFileString("/mnt/sdcard/Android/data/TestProject/archive.zip", "text1.txt"));*/
    
public static String zipFileString(String zipfilenameString filename) {
        
String s "";
        try {
            
FileInputStream is = new FileInputStream(zipfilename);
            
ZipInputStream zipinputstream = new ZipInputStream(is);
            
ZipEntry zipentry zipinputstream.getNextEntry();
            while (
zipentry != null) {
                if (
filename.equalsIgnoreCase(zipentry.getName())) {
                    
StreamToString(zipinputstream);
                    
zipinputstream.closeEntry();
                }
                
zipentry zipinputstream.getNextEntry();
            }
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
        return 
s;
    }
    
   
/* Чтение картинки из архива в Assets. Пример вызова из Activity:
    * imageview1.setImageDrawable(Unzip.zipAssetsDrawable("image1.jpg", getApplicationContext()));
    * в папке Assets открывается архив assets.zip и из него извлекается
    * картинка filename сразу в Drawable */
    
public static Drawable zipAssDrawable(String filenameContext context) {
        
Drawable d null;
        try {
            
InputStream is context.getAssets().open(zipfilename);
            
ZipInputStream zipinputstream = new ZipInputStream(is);
            
ZipEntry zipentry zipinputstream.getNextEntry();
            while (
zipentry != null) { 
                
String entryName zipentry.getName();
                if (
entryName.equalsIgnoreCase(filename)) {
                    
Drawable.createFromStream(zipinputstreamentryName);
                    
zipinputstream.closeEntry();
                }
                
zipentry zipinputstream.getNextEntry();
            }
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
        return 
d;
    }

    
/* чтение картинки из архива на диске
     * в zipfilename - путь и имя архива,
     * в filename - имя искомого файла
     * пример вызова из Assets:
     * imageview1.setImageDrawable(Unzip.zipFileDrawable("/mnt/sdcard/Android/data/TestProject/archive.zip", "image1.jpg"); */
    
public static Drawable zipFileDrawable(String zipfilenameString filename) {
        
Drawable d null;
        try {
            
FileInputStream is = new FileInputStream(zipfilename);
            
ZipInputStream zipinputstream = new ZipInputStream(is);
            
ZipEntry zipentry zipinputstream.getNextEntry();
            while (
zipentry != null) { 
                
String entryName zipentry.getName();
                if (
entryName.equalsIgnoreCase(filename)) {
                    
Drawable.createFromStream(zipinputstreamentryName);
                    
zipinputstream.closeEntry();
                }
                
zipentry zipinputstream.getNextEntry();
            }
            
zipinputstream.close();
        } catch (
Exception e) {
            
e.printStackTrace();
        }
        return 
d;
    }
    

__________________
to be or not to be - it's not a question!
2b or not 2b = ff

Последний раз редактировалось barsunduk, 15.11.2013 в 18:05.
(Offline)
 
Ответить с цитированием
Старый 15.11.2013, 20:51   #9
Romanzes
Разработчик
 
Аватар для Romanzes
 
Регистрация: 06.04.2008
Сообщений: 541
Написано 196 полезных сообщений
(для 637 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

По странному стечению обстоятельств, именно сегодня столкнулся с одной интересной технической тонкостью Андроида. Я работаю над SDK, которая автоматически встраивается в готовые Android-игры. Сегодня обнаружилось, что некоторые игры начинают падать в начале работы после перепаковки моей утилитой. Путем долгих расследований я обнаружил, что причина заключается в том, что звуки игры, хранящиеся в формате .ogg, в итоговом apk-файле оказываются в сжатом виде, в то время как в оригинальном архиве они лежали без компрессии. Поначалу я был удивлен, как это может каким-то образом влиять на что-либо. А затем нашел одну полезную статью, в которой рассказывается о том, что для многих типов ассетов любая компрессия нежелательна или даже смертельна. Самое интересное, что до версии андроида 2.3 вообще нельзя было хранить ассеты размером более 1 МБ в сжатом виде, иначе приложение падало. А у тебя вообще архив на архиве и архивом погоняет. Учти это в своем редакторе, а я не стал бы трогать это даже двенадцатиметровой палкой.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
barsunduk (16.11.2013)
Старый 16.11.2013, 21:45   #10
barsunduk
ПроЭктировщик
 
Аватар для barsunduk
 
Регистрация: 09.05.2010
Адрес: рф ро шахты
Сообщений: 177
Написано 66 полезных сообщений
(для 271 пользователей)
Ответ: загрузка картинки из архива сразу в Drawable

ок, выкидываем из ассетов архивы. там всё будет валяться в несжатом виде. архивы будут читаться только с устройства, если я когда-нибудь соберу редактор. спасибо за помощь и уместные страшилки!
*пошел выкидывать 12-метровую палку*
__________________
to be or not to be - it's not a question!
2b or not 2b = ff
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 11:16.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com