¿Por qué la muestra de documentación se divide por 2 para calcular inSampleSize para la carga de mapa de bits?

En la documentación de Android Training aparece un artículo sobre la carga de mapas de bits de gran tamaño de manera eficiente que explica el cálculo de un inSampleSize para inSampleSize de una imagen cuando se carga. Este es el ejemplo de código compartido.

 public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } 

Lo que no tiene mucho sentido para mí es el uso de halfHeight y halfWidth aquí. Vamos a caminar a través de un ejemplo del mundo real para que pueda mostrar lo que quiero decir.

Quiero cargar la foto de un usuario en una textura de OpenGL. Ya he preguntado para encontrar que el GL_MAX_TEXTURE_SIZE es 4096. El usuario selecciona una foto que es 4320×2432, así que necesito escalar eso abajo un poco.

Hago la llamada a mi método auxiliar estático proporcionado en los documentos:

 options.inSampleSize = BitmapUtils.calculateInSampleSize(options, maxTextureSize, maxTextureSize); 

Pasando por este código, halfHeight será 1216 y halfWidth será 2160, y inSampleSize sólo será diferente de 1 si ese valor dividido por inSampleSize sigue siendo mayor que la dimensión solicitada.

Cuando ejecuto esta configuración, inSampleSize se establece en 1, que no escala la imagen en absoluto, y OpenGL lanza un ajuste porque es mayor que el GL_MAX_TEXTURE_SIZE .

Mi pregunta es ¿por qué nos dividimos por dos aquí? No me importa si la mitad de mi imagen encaja en las dimensiones solicitadas, quiero que toda la imagen encaje. ¿No tendría más sentido seguir golpeando inSampleSize siempre y cuando (halfHeight / inSampleSize) > reqHeight y (halfWidth / inSampleSize) > reqWidth ?

Este fue mi malentendido de la intención de este método. Pensé que estábamos buscando un inSampleSize que descodificaría un mapa de bits para caber dentro de las dimensiones requeridas. Veo ahora que el método está destinado a devolver un valor para decodificar un mapa de bits que sería lo más cerca posible pero no menor que el tamaño solicitado.

Curiosamente, esta pregunta respondió a la mía. Estaba confundido por el método:

 // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } 

Esto no mantendría la altura y el ancho mayores que reqHeight y reqWidth. El bucle terminaría tan pronto como uno de ellos fuera menor que el valor relevante. Sin embargo, debido a que el método utiliza halfHeight y halfWeight, es un poco como dar un paso atrás tras superar la marca … o medir un paso adelante, más bien …

De todos modos, estaba pensando en el problema en cuestión y terminó con lo siguiente:

 boolean condition = (height / 2 / inSampleSize) > reqHeight && (width / 2 / inSampleSize) > reqWidth; for (; condition; inSampleSize *= 2) { } 

¿Es inapropiado utilizar un bucle for de esta manera? Tal vez sería más claro utilizar simplemente:

 while ((height / 2 / inSampleSize) > reqHeight && (width / 2 / inSampleSize) > reqWidth) { inSampleSize *= 2; } 

De todos modos, voy a tratar de responder a su pregunta real un poco mejor. Creo que este método está diseñado para minimizar el uso de memoria, no para proporcionar un mapa de bits con un tamaño exacto requerido. Un factor de 2 es un gran salto cuando se reducen las imágenes; Usted podría terminar para arriba con un bitmap apenas sobre la mitad del tamaño que usted está buscando y después tener que aumentar. Estoy aprendiendo a usar imágenes y estoy totalmente especulando, pero ¿no parecería peor que reducir la escala de una imagen que es casi el doble del tamaño requerido?

  • ¿Por qué está bloqueando glClear en OpenGLES?
  • Ayuda para rectificar escalas de línea en Android OpenGL 2.0 con RQAR
  • Recursos para aprender desarrollando juegos con ndk + opengl en C ++?
  • Android: actualiza el mapa de bits del hilo del temporizador
  • Ubuntu 16.04 Versión OpenGL no reconocida
  • Diferencia entre glOrthof y glViewPort
  • Android Canvas o Open GL ES para el juego 2d?
  • Cómo guardar bitmap de GLSurfaceView (Sólo bitmap, no toda la textura)
  • Android OpenGL2.0 que muestra texturas negras
  • Parallax XY y cálculo de la rotación
  • ¿Por qué eglMakeCurrent () falla con EGL_BAD_MATCH?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.