Problema de escalado en Android – ¿por qué la imagen es tan torpe?
No tengo gráficos 2D y experiencia de juego. Me enseñé a mí mismo por cientos de errores y decenas de horas perdidas. Comencé con el juego simple Dress Up. Utilicé Nexus 5x para el desarrollo donde una pantalla parecía bien. Cuando terminé un hito probé el juego en la tableta grande de Lenovo y el minúsculo teléfono Samsung Mini. Se veía horriblemente.
- Envoltura de texto largo en un lienzo Android
- ¿Cómo dibujar muchos rectángulos en lona con buen funcionamiento?
- Diferencia entre glOrthof y glViewPort
- Soporta múltiples proporciones en Unity
- Hoja de ruta para el desarrollo de Android
Un original vector PSD archivo parece perfecto, PNG exportación no tiene ningún problema tampoco. Pero cuando la escala de la imagen es desigual. Sé que es bitmap. Pero hay otra imagen que escala en otro lugar y se ve bien (ambas imágenes son de 32 bits):
Cuando juego algún juego de Google Play, nunca tienen problemas de escala. ¿Cómo se implementan? ¿Usan vectores? ¿Hay algún truco?
Puse todo en carpeta de assets
y aunque tomó 1 MB. He descompilado algunos apk y no tienen conjunto de variantes para cada resolución. Aunque escalan cuadros agradable.
Algunos fragmentos de código fuente:
protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.w = w; this.h = h; canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); drawCanvas = new Canvas(canvasBitmap); } protected void onDraw(Canvas canvas) { if (baseBitmap != null) { double scale = Math.min((double) w / (double) figure.getW(), (double) h / (double) figure.getH()); figure.setScaleRatio(scale); int sw = (int) (scale * figure.getW()); int x = ((w - sw) >> 1); figure.setX(x); paintDressPart(canvas, figure, figure.getMain()); if (displayedParts != null) { for (DressPart dressPart : figure.getParts()) { if (displayedParts.contains(dressPart.getId())) { paintDressPart(canvas, figure, dressPart); } } } } } private void paintDressPart(Canvas canvas, Figure figure, DressPart part) { double scale = figure.getScaleRatio(); int sh = (int) (scale * part.getH()); int sw = (int) (scale * part.getW()); int sdx = (int) (scale * part.getDestX()); int sdy = (int) (scale * part.getDestY()); scaledRect.set(figure.getX() + sdx, sdy, figure.getX() + sw + sdx, sh + sdy); Rect partRect = part.getRect(); canvas.drawBitmap(baseBitmap, partRect, scaledRect, canvasPaint); }
Y si quieres verlo tú mismo preparé el proyecto completo en GitHub para que puedas descargarlo y ejecutarlo tú mismo:
Https://github.com/literakl/DressUp
Actualizar
Downscaling chupa también. Pero gracias al comentario de Paavnet me di cuenta de que Paint importa. Vea la diferencia en una imagen:
Ejecuté la aplicación de demostración en 3,2 "AVD imagen.La imagen 278×786 es escalado a 107×303.
Actualización de Octubre
Reescribí la aplicación para usar la carpeta de recursos en lugar de los recursos. Android escalas imágenes y luego volver a escala de nuevo. A pesar de que se ve mejor que cuando no uso Android escala de recursos. Los recursos de imágenes en escala mejoran normalmente mejor que los nodpi sin escala / la imagen de activos.
Me pareció que mdpi funciona mejor. Incluso tenía imágenes xxhdpi y se veía peor que mdpi. Creo que incluso en el dispositivo xxhdpi! Pero puede ser un problema del cuadro que no fue pintado bien. La escala de recursos de Android puede suavizar los bordes de las líneas.
- Array 2D en android
- Cambiar tamaño de Android personalizado SurfaceView
- No se puede encontrar el ejemplo adecuado para la clase de sprite de OpenGL 2d que no usa GL11Ext para dibujar
- Android gl abierto más lento que la tela?
- ¿Cuáles son los mejores formatos de animación 2D que se podrían utilizar para juegos Android
- 2D API o OpenGL ES para un juego de Android 2D?
- Sprite y la animación que hace la herramienta para el juego del androide
- Dibujar sector circular
Me enfrenté a la misma cuestión .. que la escala no tan suave .. mejor método estándar
Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true);
Usted puede encontrar más tamaño optimizado convertidor en la web .. pero en realidad la mejor solución que terminó con el uso:
1er. Utilice el recurso del SVG del vector. Esto es trabajo 100% con calidad perfecta. Sólo asegúrese de que los elementos SVG son compatibles con android (consulte: https://developer.android.com/studio/write/vector-asset-studio.html )
Pros
- mejor calidad
- Tamaño eficiente
- Editable fácilmente
contras:
- No todos los elementos son compatibles.
O
2do. Proporcionar una imagen de alta resolución (uno es suficiente en xxxhdpi)
Pros
- buena calidad
contras:
- Podría conducir a problemas de rendimiento
Espero que pueda ayudar, '.
¿Usan vectores?
SVG / Vector es una solución práctica, pero el arte vectorial requiere una precisión extremadamente alta, por lo que no es adecuado para muchos estilos de arte. Es fácil de usar arte vectorial con formas básicas, pero puede ser difícil añadir un detalle simple con SVG estilos simbólicos, aunque se puede agregar Fácilmente con pintura con png,jpeg
. Puedes ver videos de patrones de rendimiento en SVG donde los googleadores sugieren SVG
para diseños de iconos. La mayoría de los juegos no lo utilizan para imágenes complejas y ricas.
Así que no voy a ir para SVG
especialmente donde pequeño detalle importa mucho en los juegos.
¿Cómo se implementan? ¿Hay algún truco?
-
Una forma es simplemente publicar la aplicación con un solo soporte de activos regulares (MDPI, HDPI) y si la densidad de pantalla requiere alta resolución, entonces mostrar un diálogo para el usuario, preguntándole si quiere descargar los activos de alta resolución.
-
Usted puede tener una mayor densidad de imágenes y la escala hacia abajo en tiempo de ejecución basados en el requerimiento de densidad de teléfono utilizando
DisplayMetrics
hecho, debe mantener la misma relación de aspecto.Conjuntar un juego hecho para una pantalla 4: 3 se ve horrible en un 16: Pero encajando un 16: 9 encendido a un 16:10, nadie pudo notar. Leer para más .
Puede utilizar esta forma para obtener fácilmente la altura y el ancho de la pantalla ( teniendo en cuenta que está utilizando SurfaceView
como mejor práctica )
DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenHeight = metrics.heightPixels; int screenWidth = metrics.widthPixels;
Para obtener una nueva anchura-altura en la rotación:
surfaceChanged(SurfaceHolder holder, int format, int width, int height)
Ese método le da la anchura / altura de su superficie, por lo que ahora podría usar:
Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)
Desde la clase Bitmap para cambiar el tamaño de las imágenes en proporción al tamaño de la superficie que está dibujando. Puede buscar en alguna técnica para encontrar factores de escala apropiados.
-
OpenGL,kotlin
puede darle ventaja para la creación de aplicaciones gráficas ricas.Con estos se puede controlar la memoria y el rendimiento de laGPU
que básicamente son el hueso de la mayoría de los juegos además de que puede tomar ventaja de controlar la prestación de manera más eficiente conGPU and native memory space
Además hay mucho más que se puede pensar, tomará algún tiempo si no está familiarizado con estos pero una vez que lo consigas pueden hacer muchos trucos mágicos. -
Webp
le ayudará a reducir el tamaño de las grandes imágenes a una diferencia considerable. Debería probar webp. (Sugerencia, webp tiene un pequeño problema para el canal alfa de la imagen en algunos dispositivos pero demasiado bueno para la compresión del tamaño de la imagen)
Conclusión: Implementa las mejores prácticas usando OpenGL, SurfaceView, NDK más cargando imágenes eficientemente usando factores de escala docs link y debería probar esto también.
También puede echar un vistazo a 9patch
imágenes 9patch
donde se pueden poner restricciones para escalar sólo una parte de la imagen en lugar de whole.it es bastante útil.
Actualización : Como se sugiere, si va a utilizar una imagen de alta resolución, entonces también mirar en esto y esto para desactivar la escala o el factor de escala de cálculo manual. Buena suerte
Nota: Los chicos se sienten libres de editar esta respuesta con información válida si lo desea.
- No se puede construir el paquete androide firmado a través de studio visual cordova
- No se puede eliminar la intención extra!