# Biblioteca Ming

Biblioteca Ming es una biblioteca de open source para la creación de ficheros SWF (Adobe Flash), realizada en C. A menudo se utiliza como un módulo PHP, permitiendo la generación de animaciones Flash en el servidor web utilizando la base de datos del mismo. Además de en PHP, la biblioteca se puede utilizar en los lenguajesC++, Perl, Python y Ruby

## Características

Ming soporta casi todas las características de Flash 4, incluyendo: formas, gradientes, bitmaps (pngs y jpegs), transformaciones ("cambio de forma"), texto, botones, acciones, símbolos gráficos ("clips de película"), soporte audio mp3, y las transformaciones de color. La única característica que está haciendo falta es los eventos de sonido.
Además, Ming no tiene absolutamente nada que ver con MNG, el descendiente animado de PNG. Los dos se usan para animación web, ambos son declarados "ming", pero solo uno se usa para hacer las engorrosas películas flash.

### Dibujando

El objeto fundamental en una película flash es una forma. O, en Ming, una SWFShape. En php, instancia un objeto SWFShape con la simple expresión:
Aunque la biblioteca Ming está escrita en código C plano, está diseñada para ser utilizada en un ambiente orientado a objetos; por consiguiente, en PHP tu puedes acceder a las funciones de dibujo de Ming mediante el objeto SWFShape. Para dibujar un cuadrado rojo de 400 unidades en cada lado con una anchura de línea de 20 unidades haz:
Primero, una nota acerca de las unidades: la especificación flash indica una escala de veinte unidades por píxel, así, el cuadrado generado mediante el código anterior tendría 20 píxeles de lado y una línea de un píxel. Sin embargo, esta escala no es forzada en ninguna parte; la escala depende únicamente del tamaño que tu especifiques cuando insertes la película en tu código html y del tamaño del marco que establezcas dentro de la película (lo puedes cambiar después). Nosotros podríamos haber dibujado el cuadrado también de 20 unidades con una línea de 1 unidad. De cualquier modo, nosotros conseguimos el mismo cuadrado si escalamos la película junto con esta.
Ahora, probablemente notaste que el método "drawLineto" únicamente recibe dos argumentos considerando que una línea normal tiene cuatro parámetros, estos son una coordenada "x" y una coordenada "y" para ambos puntos finales. Y probablemente concluiste que esto significa que el dibujo en Ming es basado en pluma; es decir, el objeto forma guarda una referencia de la ubicación de la pluma imaginaria en la superficie del dibujo, y los comandos de dibujo referencian y afectan implícitamente la ubicación de la pluma. Esto debió ser suficiente para que aprendieras que drawLineTo tiene una función drawLine relacionada que usa posicionamiento relativo en lugar de coordenadas absolutas. En otras palabras, las funciones de dibujo anteriores podrían reemplazarse por:
y obtendríamos el mismo cuadrado rojo.
El método setLine recibe cuatro (o cinco) los argumentos: el ancho de la línea, y el rojo, verde, y azul (y opcionalmente la transparencia), componentes del color de la línea. Cuando fijas el estilo de línea, este se aplica a todos los comandos de dibujo subsecuentes hasta que cambie de nuevo el estilo de línea con setLine. Para no utilizar estilo de línea (que, a propósito, es el valor por defecto para las formas), simplemente fija el ancho en cero.
Finalmente, estos son dos de los comandos de dibujo más útiles:
Mueve la pluma a las coordenadas (x,y) sin dibujar línea (y movePen es su primo más cercano), mientras que:
Dibuja una curva cuadrática bezier simple desde la ubicación actual de la pluma hasta el punto (ax,ay) usando el punto (cx,cy) como un punto de control. Como esperamos, drawCurve hace lo mismo, excepto que usa coordenadas relativas a la posición actual de la pluma.

### Estilos de relleno

Esto puede llegar a ser una cosa muy confusa acerca de Ming, de manera que haré algunas aclaraciones antes. El formato swf está diseñado para ser compacto y fácil de utilizar, esto significa que las optimizaciones en los atributos de formas son hechas en el acto, no por el reproductor.
Específicamente, cuando estás definiendo una forma debes decirle al reproductor qué porción del espacio entre las líneas debe quedar rellena. La razón para esto (y me siento libre de saltar este párrafo, y no estará en el ejemplo) es que el reproductor flash dibuja la forma mientras verifica las líneas, y como este recorre cada borde en su definición de forma, revisa los registros de relleno del lado izquierdo y del lado derecho para ver que estilo de relleno se está aplicando sobre la línea. Si el borde es más denso al norte que al sur, el explorador de línea se está moviendo al lado derecho del borde mientras cruza sobre la línea desde la derecha hacia la izquierda, así empieza rellenando con el estilo de relleno del borde del lado derecho. Si el borde fuera más denso al sur que al norte, usaría el estilo relleno del lado izquierdo.
Fija el relleno del lado izquierdo y del lado derecho mediante los métodos setRightFill y setLeftFill. Estos simplemente trabajan como setLine, se aplican a todos los bordes subsecuentes hasta que cambie el estilo de relleno de nuevo. setRightFill y setLeftFill reciben un argumento, un objeto SWFFill.

### SWFFill

SWFFill abarca rellenos sólidos, gradientes, y mapas de bits. En lugar de instanciar un SWFFill directamente, solicitas un SWFShape para que se cree uno para utilizar el método addFill de SWFShape. La lógica detrás de esto es que el relleno sólo tiene significado dentro del contexto de la forma, y veremos por qué brevemente. addFill viene en una variedad de formatos, uno para cada uno de los tipos de relleno que puede crear: colores sólidos, mapas de bits, y gradientes.
Crea un relleno de color sólido con los componentes especificados rojo, verde, y azul (y opcionalmente transparencia). Dibujemos un cuadrado rojo relleno:
Nosotros usamos setRightFill aquí porque dibujamos el contorno del cuadrado en sentido de las manecillas del reloj, así, el interior del cuadrado se rellena desde el borde del lado derecho. Si hubiéramos dibujado el cuadrado un sentido contrario a las agujas del reloj, habríamos usado el método setLeftFill.

### SWFBitmap

Para agregar un relleno de mapa de bits a una forma, usamos:
Donde el mapa de bits es un objeto SWFBitmap, creado con,:
Donde filename es el nombre de un jpeg o un archivo dbl. Un archivo "dbl" es un fichero png convertido mediante la utilidad "png2dbl" el cual Ming puede procesar más fácilmente. (Estas conversiones son un "rasgo" de ming que usted encontrará de vez en cuando. La única razón por la que le pedimos que pase por estos pasos extra es para no tener que utilizar varias bibliotecas de apoyo como libpng para usar ming. Algún día autoconf ordenará este lío y será capaz de leer pngs, gifs y ttfs con una simple llamada a una función.) El programa png2dbl es incluido en el paquete fuente de Ming. También sea consciente de que Ming actualmente puede procesar básicamente archivos comprimidos jpeg. No trabaja la lectura básica, optimizada y progresiva de jpegs.
El argumento opcional máscara especifica un archivo "msk" que agrega un canal de transparencia a un mapa de bits jpeg. El archivo msk se crea con "gif2mask", también incluido en el paquete fuente Ming. El archivo gif de entrada debe ser del mismo tamaño del jpeg. El mapa de bits resultante es opaco donde la máscara de imagen es blanca, semi-transparente donde es gris, y totalmente transparente donde es negra. Es decir, el valor de los píxeles del archivo de máscara se usa como el nivel de transparencia para los píxeles de la imagen jpeg.
El argumento flags puede ser SWFFILL_CLIPPED_BITMAP o SWFFILL_TILED_BITMAP, e indica si los mapas de bits deben seguir una secuencia (qué es el valor por defecto, en lugar del argumento flags) o deben superponerse, respectivamente.
SWFBitmap también tiene métodos para obtener las dimensiones de su imagen:
Qué le permite dibujar un rectángulo del mismo tamaño de tu mapa de bits, que de hecho es bastante útil.

### SWFGradient

Los gradientes, como ya bien sabes, son las transiciones uniformes entre colores. En Flash, los gradientes pueden ser lineales o radiales, pueden contener hasta ocho colores, y pueden tener transparencia. Para construir una relleno de gradiente, primero cree un objeto SWFGradient:
Entonces fija los valores iniciales mediante:
Donde ratio es un número entre 0 y 1, y r, g, y b (y opcionalmente a) especifican los componentes rojo, verde, y azul (y transparencia) de la ubicación específica del gradiente. Debes (tienes que hacerlo) agregarlos en orden de incremento de ratio.
Por ejemplo, así es como creas un simple gradiente negro a blanco:
Finalmente, tu agrega el gradiente a su forma con:
Donde gradient es su recién creado SWFGradient y las banderas son SWFFILL_RADIAL_GRADIENT para un (sorpresa!) gradiente radial, o SWFFILL_LINEAR_GRADIENT para el viejo y aburrido gradiente lineal. Si no se proporcionan banderas, el gradiente por defecto es lineal.

### Transformando su relleno

Suponiendo que para ti el nuevo gradiente y relleno con mapas de bits no son muy divertidos en su estado por defecto, nosotros amablemente hemos proporcionado los siguientes métodos:
Mueve el relleno a las coordenadas (el x,y):
Gira el relleno deg grados, y:
Fija la escala de relleno en xscale en dirección x y yscale en dirección y. Si sólo se proporciona un argumento, ambas dimensiones son escaladas por xscale. Por último:
Sesga el relleno por s en el eje x o en el eje y. Una s de 0 no es sesgada, una s de 1.0 es sesgada a un ángulo de 45 grados.

### Animación

Ahora que hemos definido una forma, seguro nos gustaría poder verla. Para hacer esto, necesitamos un lienzo en el cual dibujar. Ese lienzo es el venerado SWFMovie.
Crea un nuevo objeto SWFMovie, base para la animación. Nosotros podemos usar
Para fijar el color del fondo:
Para fijar el frame rate (en frames por segundo), y:
Para fijar el tamaño de la película. Acuérdate lo que dijimos acerca del escalamiento: el tamaño de la presentación establecido en su html determina el tamaño real. Las dimensiones de la película fijadas aquí determinan la escala en la que sus formas serán dibujadas. Si usted fija el tamaño de su película en 3200x2400 y lo empotra en una página html de 320x240, sus formas serán 1/10 del tamaño que usted especificó en sus comandos de dibujo.
Tu forma no se dibujará en la película hasta que usted cree una instancia de ella llamando:
Este método crea una instancia de la forma en la película y retorna una referencia con la que puede alterar la apariencia de la instancia. Puedes, de hecho, agregar la misma forma a su película tantas veces como quieras (siendo razonable, claro) y usar los apuntadores retornados para referenciar cada uno individualmente.
Usar Ming para hacer películas flash es análogo a usar una cámara de movimiento: debes poner las formas en su lienzo, colóquelos como usted guste, pulse entonces el obturador para grabar el arreglo y avance al siguiente frame. Coloca:
El paso "arreglo" es realizado llamando métodos proporcionados por el apuntador a la instancia (que se generó con el método add de SWFMovie, recuerdas?). Estos métodos son idénticos a los métodos de transformación que vimos en SWFFill, excepto que cada uno tiene una versión relativa que actúa en relación con la posición actual, escala, rotación, e inclinación. Por ejemplo:
Mueve el objeto a las coordenadas (el x,y), mientras:
Desplaza el objeto con el vector (el x,y). El resto de los métodos son:
Confió en que ya leíste la sección de transformación de rellenos y puedes deducir lo que hacen estos métodos ok?.
Tu también puedes quitar un objeto de la lista de despliegue si estás cansado de su fisonomía:

### Transformar colores

Otra cosa que podemos hacer es alterar el color del objeto:
El primer método agrega un valor constante a cada uno de los canales del objeto de despliegue: rojo, verde, y azul (y opcionalmente transparencia). El segundo multiplica los canales por los valores de escala dados.
Nota que estos valores pueden ser negativos; para invertir el canal azul de un objeto desplegado, tu utilizarías:
Nota también que estos métodos no son conmutativos, así:
Finalmente cuando tengas todo listo, llama a Ming para enviar la película al navegador
El comando header hace que tu servidor web le diga al navegador del cliente que esto es, de verdad, una película flash.
Para un ejemplo rápido, hagamos que el cuadrado rojo que creamos previamente (inmóvil en $s para ahorrarle a mis dedos un poco de uso) el giro:
Nosotros estamos siendo terriblemente diestros aquí al permitir que el ciclo de animación vuelva al principio después de rodar el pobre cuadrado sólo 75 grados ya que el primer frame es idéntico a una rotación de 90 grados. Verdaderamente muy inteligentes nosotros.
El texto
Primero, carga una fuente:
Donde filename es un archivo fdb. (Sí, otro formato de archivo ad hoc - crea archivos fdb desde las plantillas de archivo flash swt con la utilidad makefdb de Ming.) El objeto SWFFont le proporciona alguna información métrica de la fuente:
Cada método produce la métrica solicitada como un número, escalado a una altura de fuente de 1024. A menos que esté desplegando tu texto a una altura de 1024, necesitarás multiplicar el número retornado por alto/1024.
Puedes ver el manejo de texto mediante:
Agrega un SWFText a tu película con el método add de SWFMovie animarlo con el apuntador retornado, así como con las formas.

### SWFButton

Los botones pueden tener varios formas asociadas con ellos, el appearace general del botón; un encima de la forma, desplegó cuando el ratón mueve encima del botón; un baje la forma, desplegó cuando los clics del usuario abajo en el botón; y una región del golpe que nunca se muestra pero define el área del clickable del botón.
Crea un botón con:
Y agrega una forma al botón declara con:
Nota que esto agrega la misma forma a todos los estados que los medios que el área del clickable está igual que el área arrastrado de la forma y que el botón parece el mismo cuando tienes el mouse encima de él. Los botones en nuestro ejemplo no serán los mono-cubos de diversión, o, pero nosotros haremos una región del golpe separada:
Sin esto, la región del golpe sería sólo el interior del texto del titular, qué simplemente sería raro. Ahora apretemos fuera esos botones:
Así ahora que nosotros tenemos nuestros botones construidos, animémoslos. Estos dos archivos contienen funciones que realizan las varias transiciones entre los titulares:
Por ejemplo, la función siguiente de infuncs.php resbala el botón de la izquierda mientras la transparencia completa a totalmente opaco:
Todas las funciones en infuncs.php toman una película y una forma como los argumentos, y devuelve un caso de la forma en la película. Las funciones en outfuncs.php toman la película, la forma, y el caso creadas se aseguran que la lona está vacía cuando ellos vuelven.
Las funciones se listan en las series $infuncs y $outfuncs, mientras permitiéndonos formar, sin referente al php principal codifique en absoluto. Aquí es el pedazo final de código que realiza la animación: