Android: ¿debería usar GLSurfaceView en lugar de Canvas para evitar bitmapfactory oom?

Mi aplicación necesita cargar un plano de planta del edificio y luego dibujar objetos (muebles) en el plano de planta. La imagen del plano de planta es un PNG de 2500 x 1500 y 240 Kb, pero Frackin' BitmapFactory bloquea la mayoría de los dispositivos al requerir más de 12 Mb de almacenamiento dinámico para crear el mapa de bits, lo que genera un error de memoria insuficiente. Permítanme ser claro aquí: esto no es, hasta donde puedo decir, una pérdida de memoria, y bitmap.recycle() no hace nada porque se bloquea al crear la primera imagen, la primera vez. Leer la imagen con inSampleSize no ayuda a menos que use un tamaño de muestra que haga que la imagen sea irreconocible. Toda esta situación es una locura. Estoy probando en un Droid 3, HTC Inspire y dos emuladores 2.3. El HTC cargará el mapa, al igual que el emulador con un (ridículo) tamaño de pila de 128Mb. Las implementaciones de esta aplicación se usarán en todo el espectro de usuarios de Android, por lo que no puedo hacer nada dirigido a más de 2.3 dispositivos.

Aquí está mi código actual, que me da una imagen inutilizable (de otra publicación SO, lo siento, perdí el enlace):

BitmapFactory.Options o=new BitmapFactory.Options();
        o.inJustDecodeBounds=true;
        BitmapFactory.decodeResource(getResources(), resourceId, o);


        //Find the correct scale value. It should be the power of 2.
        int scale=16;
        while((o.outWidth/scale)>=REQUIRED_SIZE || (o.outHeight/scale)>=REQUIRED_SIZE)
            scale*=2;

        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inSampleSize = scale;

        Bitmap base_image;
        try {
            base_image = BitmapFactory.decodeResource(getResources(), resourceId);
        } catch (Error e1) {
            base_image = BitmapFactory.decodeResource(getResources(), resourceId, options);
        }

¿GLSurfaceView resolvería mi problema aquí? Lo necesito para 1) cargar la imagen del plano de planta, 2) permitirme dibujar objetos y etiquetas de texto programáticamente, y 3) admitir el zoom y reaccionar al tacto en función de las coordenadas del plano de planta. Si esta es la respuesta, ¿alguien puede recomendar un buen tutorial para un trabajo 2D básico como este?

preguntado el 12 de junio de 12 a las 17:06

Sugerencia: el tamaño de archivo de un PNG no significa nada, ya que está comprimido. Cuando se usa en la memoria, tiene (generalmente) 32 bits o 16 bits (4 o 3 bytes) para cada píxel. Esto significa que su imagen de 2500 x 1500 ocupa 15 megabytes de memoria. -

Correcto, lo encontré en otra pregunta. ¿Cómo me recomiendas abordar la situación? -

1 Respuestas

Hay muchas formas de disminuir el uso de memoria para mapas de bits, si elige OpenGL, puede usar texturas precomprimidas que puede enviar directamente a la memoria de video. Android admite texturas ETC1 de forma nativa, si no recuerdo mal, ETC disminuye el tamaño en un 25%. Sin embargo, dado que no tiene experiencia en openGL y también necesita realizar acciones un poco más complejas, como dibujar texto, esta podría no ser la mejor acción para usted (aunque probablemente obtendrá el mejor rendimiento en dispositivos más antiguos a través de este método) . Podría considerar usar cualquiera de los motores que existen (AndEngine o Box2d son populares).

Una opción más rápida y posiblemente mejor para usted podría ser crear representaciones vectoriales (como SVG archivos) de sus planos de planta (esto debería ser posible si tiene planos simples que consisten en un color de fondo y líneas para las paredes). Luego dibuje esto usando el Path class o una biblioteca externa si desea imágenes más avanzadas.

Respondido el 12 de junio de 12 a las 17:06

Estoy obteniendo los archivos del plano de planta de un tercero y no creo que sea posible obtener nada más que PNG. Buscaré en ETC para ver si puedo entenderlo/usarlo. Gracias. - cschryer

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.