Creando iconografía para Android en Ubuntu

Introducción

Llevo algunas semanas actualizando y renovando todos los iconos de una de las aplicaciones que he desarrollado para Android y que es prima hermana de My-Weather-Indicator en Ubuntu. Para ello, y tal y como he comentado en alguna otra ocasión, utilizo como herramienta de desarrollo Inkscape, básicamente por la ventaja del uso de las imágenes vectoriales, pero, si bien, es posible utilizarlas directamente en Android, es mas sencillo y cómodo, utilizar imágenes en formato PNG.

Esto lleva a la necesidad de convertir las imágenes vectoriales en formato SVG a PNG, pero además, es necesario crear iconos para las distintas resoluciones de pantalla. Como todo en esta vida, y mas en el mundo informático, cada “maestrillo” tiene su “librillo”, así que en este artículo voy a mostrar la forma en la que lo hago por si puede ser de ayuda para otros, así como seguro que hay quien aporta su propia solución que seguro mejora o completa la que yo ofrezco.

mientras_349.png

Creando iconografía para Android en Ubuntu

Uno de los inconvenientes que mas me incomodan del desarrollo de aplicaciones para Android, es la necesidad de tener que crear iconos para todas y cada una de las resoluciones de pantalla, y además dependiendo de la versión de Android, es posible que sea necesario incluso cambiar de color para algunos iconos, como puede ser los de notificación, donde para versiones SDK previas a la 11 son colores grises, mientras que para versiones posteriores el color es blanco.

Cambiando colores

Una vez que he creado toda la colección de iconos en formato SVG necesarios para mi aplicación, podemos empezar con el proceso de conversión a PNG.

En mi caso, hasta la fecha, todos los iconos que he ido haciendo son monocromáticos, y para facilitarme el trabajo los hago en color negro. Así el primer paso es cambiar el color según la versión que necesito. Esto se puede hacer con un sencillo script,

#/bin/bash
for f in *.svg
do
    echo "Processing $f file.."
    sed  -i  's/#000000/#ffffff/g' "$f"
done

Con este sencillo script cambiamos el color negro (#000000) por el color blanco (#ffffff), aunque podríamos cambiar a cualquier otro color, evidentemente.

Creando la iconografía

El siguiente paso sería crear la iconografía necesaria según la resolución de para nuestra aplicación, si además lo combinamos con el script anterior, el resultado sería algo como lo que sigue a continuación,

#/bin/bash
if [ -d "drawable-ldpi" ]; then
  rm "drawable-ldpi"
fi
if [ -d "drawable-mdpi" ]; then
  rm "drawable-mdpi"
fi
if [ -d "drawable-hdpi" ]; then
  rm "drawable-hdpi"
fi
if [ -d "drawable-xhdpi" ]; then
  rm "drawable-xhdpi"
fi
if [ -d "drawable-xxhdpi" ]; then
  rm "drawable-xxhdpi"
fi
if [ -d "drawable-xxxhdpi" ]; then
  rm "drawable-xxxhdpi"
fi
mkdir "drawable-ldpi"
mkdir "drawable-mdpi"
mkdir "drawable-hdpi"
mkdir "drawable-xhdpi"
mkdir "drawable-xxhdpi"
mkdir "drawable-xxxhdpi"
for f in *.svg
do
    sed  -i  's/#000000/#ffffff/g' "$f"
    inkscape -z -e "drawable-ldpi/${f%%.*}.png" -w 36 -h 36 "$f"
    inkscape -z -e "drawable-mdpi/${f%%.*}.png" -w 48 -h 48 "$f"
    inkscape -z -e "drawable-hdpi/${f%%.*}.png" -w 72 -h 72 "$f"
    inkscape -z -e "drawable-xhdpi/${f%%.*}.png" -w 96 -h 96 "$f"
    inkscape -z -e "drawable-xxhdpi/${f%%.*}.png" -w 144 -h 144 "$f"
    inkscape -z -e "drawable-xxxhdpi/${f%%.*}.png" -w 192 -h 192 "$f"
done

Donde con los primeros comandos borramos los directorios en caso de que existan, posteriormente los creamos de nuevo, y a partir de ahí convertimos cada uno de los archivos con extensión SVG en su correspondiente versión PNG para la resolución de pantalla que toca.

Si además queremos tener en cuenta las versiones antiguas de android, añadiremos los correspondientes -v11. Pero ahora debemos intercalar el cambio de color para que funcione correctamente, lo que finalmente queda recogido en el siguiente script,

#/bin/bash
if [ -d "drawable-ldpi" ]; then
  rm "drawable-ldpi"
fi
if [ -d "drawable-mdpi" ]; then
  rm "drawable-mdpi"
fi
if [ -d "drawable-hdpi" ]; then
  rm "drawable-hdpi"
fi
if [ -d "drawable-xhdpi" ]; then
  rm "drawable-xhdpi"
fi
if [ -d "drawable-xxhdpi" ]; then
  rm "drawable-xxhdpi"
fi
if [ -d "drawable-xxxhdpi" ]; then
  rm "drawable-xxxhdpi"
fi
mkdir "drawable-ldpi"
mkdir "drawable-mdpi"
mkdir "drawable-hdpi"
mkdir "drawable-xhdpi"
mkdir "drawable-xxhdpi"
mkdir "drawable-xxxhdpi"
for f in *.svg
do
    sed  -i  's/#000000/#ffffff/g' "$f"
    inkscape -z -e "drawable-ldpi/${f%%.*}.png" -w 36 -h 36 "$f"
    inkscape -z -e "drawable-mdpi/${f%%.*}.png" -w 48 -h 48 "$f"
    inkscape -z -e "drawable-hdpi/${f%%.*}.png" -w 72 -h 72 "$f"
    inkscape -z -e "drawable-xhdpi/${f%%.*}.png" -w 96 -h 96 "$f"
    inkscape -z -e "drawable-xxhdpi/${f%%.*}.png" -w 144 -h 144 "$f"
    inkscape -z -e "drawable-xxxhdpi/${f%%.*}.png" -w 192 -h 192 "$f"
done
#/bin/bash
if [ -d "drawable-ldpi-v11" ]; then
  rm "drawable-ldpi-v11"
fi
if [ -d "drawable-mdpi-v11" ]; then
  rm "drawable-mdpi-v11"
fi
if [ -d "drawable-hdpi-v11" ]; then
  rm "drawable-hdpi-v11"
fi
if [ -d "drawable-xhdpi-v11" ]; then
  rm "drawable-xhdpi-v11"
fi
if [ -d "drawable-xxhdpi-v11" ]; then
  rm "drawable-xxhdpi-v11"
fi
if [ -d "drawable-xxxhdpi-v11" ]; then
  rm "drawable-xxxhdpi-v11"
fi
mkdir "drawable-ldpi-v11"
mkdir "drawable-mdpi-v11"
mkdir "drawable-hdpi-v11"
mkdir "drawable-xhdpi-v11"
mkdir "drawable-xxhdpi-v11"
mkdir "drawable-xxxhdpi-v11"
do
    sed  -i  's/#ffffff/#666666/g' "$f"
    inkscape -z -e "drawable-ldpi-v11/${f%%.*}.png" -w 36 -h 36 "$f"
    inkscape -z -e "drawable-mdpi-v11/${f%%.*}.png" -w 48 -h 48 "$f"
    inkscape -z -e "drawable-hdpi-v11/${f%%.*}.png" -w 72 -h 72 "$f"
    inkscape -z -e "drawable-xhdpi-v11/${f%%.*}.png" -w 96 -h 96 "$f"
    inkscape -z -e "drawable-xxhdpi-v11/${f%%.*}.png" -w 144 -h 144 "$f"
    inkscape -z -e "drawable-xxxhdpi-v11/${f%%.*}.png" -w 192 -h 192 "$f"
    sed  -i  's/#666666/#ffffff/g' "$f"
done

En la última línea devolvemos el archivo SVG a su formato original.

Reducir el peso de las imágenes

Por último, y no menos importante, queda el hecho de que tanto crear versiones, el resultado es que dependiendo del número de imágenes que tenga tu aplicación puede resultar en una paquete de dimensiones descomunales.

La solución pasa por reducir el peso de las imágenes. Para ello, existen diferentes herramientas, pero en la propia página de desarrolladores de Google nos proponen dos opciones, OptiPNG o Pngcrush.

De estas dos aplicaciones, y tras realizar algunas pruebas con ellas para ver cual era el mejor resultado, finalmente me he decantado por OptiPNG, así que podemos incorporarlo a nuestro script, que finalmente quedaría algo como,

#/bin/bash
if [ -d "drawable-ldpi" ]; then
  rm "drawable-ldpi"
fi
if [ -d "drawable-mdpi" ]; then
  rm "drawable-mdpi"
fi
if [ -d "drawable-hdpi" ]; then
  rm "drawable-hdpi"
fi
if [ -d "drawable-xhdpi" ]; then
  rm "drawable-xhdpi"
fi
if [ -d "drawable-xxhdpi" ]; then
  rm "drawable-xxhdpi"
fi
if [ -d "drawable-xxxhdpi" ]; then
  rm "drawable-xxxhdpi"
fi
mkdir "drawable-ldpi"
mkdir "drawable-mdpi"
mkdir "drawable-hdpi"
mkdir "drawable-xhdpi"
mkdir "drawable-xxhdpi"
mkdir "drawable-xxxhdpi"
for f in *.svg
do
    sed  -i  's/#000000/#ffffff/g' "$f"
    inkscape -z -e "drawable-ldpi/${f%%.*}.png" -w 36 -h 36 "$f"
    inkscape -z -e "drawable-mdpi/${f%%.*}.png" -w 48 -h 48 "$f"
    inkscape -z -e "drawable-hdpi/${f%%.*}.png" -w 72 -h 72 "$f"
    inkscape -z -e "drawable-xhdpi/${f%%.*}.png" -w 96 -h 96 "$f"
    inkscape -z -e "drawable-xxhdpi/${f%%.*}.png" -w 144 -h 144 "$f"
    inkscape -z -e "drawable-xxxhdpi/${f%%.*}.png" -w 192 -h 192 "$f"
done
#/bin/bash
if [ -d "drawable-ldpi-v11" ]; then
  rm "drawable-ldpi-v11"
fi
if [ -d "drawable-mdpi-v11" ]; then
  rm "drawable-mdpi-v11"
fi
if [ -d "drawable-hdpi-v11" ]; then
  rm "drawable-hdpi-v11"
fi
if [ -d "drawable-xhdpi-v11" ]; then
  rm "drawable-xhdpi-v11"
fi
if [ -d "drawable-xxhdpi-v11" ]; then
  rm "drawable-xxhdpi-v11"
fi
if [ -d "drawable-xxxhdpi-v11" ]; then
  rm "drawable-xxxhdpi-v11"
fi
mkdir "drawable-ldpi-v11"
mkdir "drawable-mdpi-v11"
mkdir "drawable-hdpi-v11"
mkdir "drawable-xhdpi-v11"
mkdir "drawable-xxhdpi-v11"
mkdir "drawable-xxxhdpi-v11"
do
    sed  -i  's/#ffffff/#666666/g' "$f"
    inkscape -z -e "drawable-ldpi-v11/${f%%.*}.png" -w 36 -h 36 "$f"
    inkscape -z -e "drawable-mdpi-v11/${f%%.*}.png" -w 48 -h 48 "$f"
    inkscape -z -e "drawable-hdpi-v11/${f%%.*}.png" -w 72 -h 72 "$f"
    inkscape -z -e "drawable-xhdpi-v11/${f%%.*}.png" -w 96 -h 96 "$f"
    inkscape -z -e "drawable-xxhdpi-v11/${f%%.*}.png" -w 144 -h 144 "$f"
    inkscape -z -e "drawable-xxxhdpi-v11/${f%%.*}.png" -w 192 -h 192 "$f"
    sed  -i  's/#666666/#ffffff/g' "$f"
done

optipng -o7 drawable-ldpi/*.png
optipng -o7 drawable-ldpi-v11/*.png
optipng -o7 drawable-mdpi/*.png
optipng -o7 drawable-mdpi-v11/*.png
optipng -o7 drawable-hdpi/*.png
optipng -o7 drawable-hdpi-v11/*.png
optipng -o7 drawable-xhdpi/*.png
optipng -o7 drawable-xhdpi-v11/*.png
optipng -o7 drawable-xxhdpi/*.png
optipng -o7 drawable-xxhdpi-v11/*.png
optipng -o7 drawable-xxxhdpi/*.png
optipng -o7 drawable-xxxhdpi-v11/*.png

Conclusiones

Desde luego que el primer paso sería planificar para que dispositivos, tanto en resolución de pantalla, como en versión de SDK, está dirigida la aplicación con el objetivo de reducir al máximo el tamaño del paquete. Actualmente esto es un problema para determinados dispositivos, tal y como sucedía hace unos pocos de años con los ordenadores de sobremesa, y ahora prácticamente no nos preocupamos de almacenar todo tipo de documentación que probablemente nunca utilizaremos.

Se trata de una sencilla solución que he adoptado para facilitarme el desarrollo de aplicaciones para Android en Ubuntu.