rubendelblanco / openrpg

Rolemaster manager
5 stars 3 forks source link

Gestor de imágenes #5

Open rubendelblanco opened 5 years ago

rubendelblanco commented 5 years ago

Una opción en el menú de la aplicación es subir imágenes (hacer un CRUD) y poder modificarlas, cortarlas, etc. podríamos poner más opciones como generar filtros aunque eso igual ya es subirse a la parra.

En cualquier caso que menos que:

Hay que darle una vuelta pero probablemente necesitaremos un modelo propio para las imágenes. Una tabla con id y url relativa o absoluta a la imagen que se almacenaría en una carpeta public/images. Dentro de ese directorio podríamos crear otros separados por campañas, usuarios, etc.

Como ya digo, hay que pensar en los detalles pero la funcionalidad es necesaria.

rubendelblanco commented 5 years ago

Para esta funcionalidad creo que lo mejor es usar Imagick https://www.php.net/manual/es/book.imagick.php mirar su API y ver qué funcionalidades pueden estar bien implementar para una aplicación de este estilo.

Que a mí se me ocurra las funcionalidades básicas que podemos necesitar son las mismas que vienen en esta web https://fengyuanchen.github.io/photo-editor/ pero sin los efectos flip. Una opción de resize también sería necesaria. Es decir, si la imagen es de 800px de ancho hacer que pueda ser de 400px (por ejemplo) y que el alto reescale para no perder la proporción. Otro ejemplo que puede servir de inspiración es este site que yo siempre visito cuando necesito hacer algo de esto https://fengyuanchen.github.io/cropperjs/

Quizá crear algún filtro puede estar bien pero eso lo dejo al albur de quien desarrolle esto.

El tema del almacenaje ya es más peliagudo porque hay que pensarlo bien. Las imágenes irán en la carpeta public/images. Eso está claro pero ¿a partir de aquí cómo lo gestionamos? En wordpress por ejemplo el gestor multimedia (no solo almacena imágenes) clasifica las carpetas por año y mes. Es decir que si subes algo el 8 de mayo de 2018, la ruta es uploads/2018/5 . No digo que tenga que ser así, solo pongo el ejemplo para que se entienda mi pregunta.

Para entender mejor el problema diré que en principio las imágenes que se van a almacenar son avatares de personajes, puede que también de usuarios, armas, items (cualquier objeto de equipo que no sea armas), mapas, monstruos y criaturas, puede que hechizos... Y de momento eso es lo que se me ocurre. Con esto en mente un posible método es almacenar las imágenes en carpetas estructuradas así:

EN CONSTRUCCIÓN/MEDITACIÓN

rubendelblanco commented 5 years ago

No tengo muy claro el tema de cómo almacenar las imágenes en carpetas, la verdad. Si alguien me puede sugerir cosas, adelante.

Os doy unos conceptos generales de cómo va a ser la app en este sentido...

Cada usuario puede tener, y seguramente tendrá, varios personajes. Por ejemplo, si muere uno o se retira o si el jugador está jugando varias campañas.

La campaña no es más que una saga de aventuras, nada más. Pero sirve para englobar a ciertos personajes en ella. Por ejemplo, la campaña se puede llamar "La batalla por Emer" o "Baldur's Gate" o nada que tenga que ver con la ambientación, por ejemplo "partidas con los amigos de Madrid" (aunque este nombre mola menos). No es más que eso. Entonces, un usuario ¿debería tener avatar? Lo digo porque sus personajes SÍ lo tendrán pero a lo mejor lo de ponérselo a un usuario sobra. No sé...

Por otro lado, la aplicación tendrá mapas y otras imágenes para ilustrar la partida. Esto es concreto de una campaña dado que cada partida tendrá sus propios mapas e imágenes, claro.

Luego está el tema de los objetos (equipo, armas, armadura) ¿debería ir todo en una misma carpeta de imágenes? Hay que tener en cuenta que en una aventura unos personajes pueden encontrarse el anillo de fuego de la bruja Morlovia que puede tener una imagen X pero esa imagen por supuesto se puede reutilizar para otros objetos ya sean de esa campaña u otra ¿Debemos clasificar las imágenes en función del tipo de equipo? Si es armas, una carpeta llamada armas, otra para las imágenes de armaduras, etc

Donde no tengo dudas es en los hechizos. Los hechizos son comunes a todas las campañas de Rolemaster así que pueden ir en una carpeta común pero...¿y el resto de las cosas? ¿Deben ir en carpetas separadas en función de la campaña o nos dejamos de historias, calsificamos las carpetas en función del tipo de cosa que representan (equipo, personajes, etc.) y ya está?

No sé. Qué opináis. Igual me estoy liando mucho yo solo.

sonirico commented 5 years ago

La estructura de ficheros y directorios para organizar las imágenes a la hora de subirlas, me parece un mero detalle de implementación, fácilmente abstraible en un módulo/clase que provea una interfaz uniforme sobre el CRUD de una imagen, dejando el driver de almancenamiento como un setting de configuración.

Se sobreentiende que en una primera iteración, habrá una tabla en la bbdd para mapear una imagen (cuyo nombre deberia ser renombrado en su primer guardado a un UUID), con diferentes tamaños (una columna para la ruta de la imagen en 256px, otra para 128px, icons, original...) que apunten a un path relativo en el sistema de ficheros.

Pero, realmente y para hacer esto bien, la funcionalidad tiene que contemplar un storage tanto en disco local, un minion remoto, NTFS o un S3. Lo dejo como apunte, porque esto que ahora parece una fumada, es lo típico que impide escalar horizontalmente en el futuro. Lo mismo pasa con dejar las imagenes en filesystem y luego olvidarselas a la hora de hacer un backup. Ya me ha pasado. Esto último se arreglaría moviendolas de FS a un blob en MySQL, pero como todo, lo que simplifica la gestión moviendo todos los datos a la misma fuente de verdad, degrada el rendimiento de ésta.

Tras apagar el cigarro, lo que yo haría sería una entidad (a mayores del controlador) que gestione el CRUD sobre imágenes, y las dejaría todas en public/images/<image_uuid>/{icon.jpeg|128.jpeg|256.jpeg}. Andarse complicando creando y borrando directorios tiene sentido cuando las imagenes van a ser tantas, que las búsquedas entre tanto i-nodo se degradarían. Si tuviéramos la fortuna o desgracia de llegar a ese punto, lo que se hace en mover el storage a un sistema gestionado por terceros o incluso un microservicio propio de static files management.

danirod commented 5 years ago

Por ayudar a pegarle un patadón a esto que lo levante, mis $0.02:


La campaña no es más que una saga de aventuras, nada más. Pero sirve para englobar a ciertos personajes en ella. Entonces, un usuario ¿debería tener avatar? Lo digo porque sus personajes SÍ lo tendrán pero a lo mejor lo de ponérselo a un usuario sobra. No sé...

¿Se le quiere dar un artwork propio a cada personaje? Si la respuesta es sí, entonces lo de tener avatar es superfluo y se puede tirar de la API de Gravatar para sacar un avatar a partir del hash si nos ponemos caprichosos, pero sobra. Si la respuesta es no, entonces por no duplicar información, se le puede dar un avatar a un User y hacer que el personaje utilice el avatar del user al que va asociado sin más.


El tema del almacenaje ya es más peliagudo porque hay que pensarlo bien. Las imágenes irán en la carpeta public/images. Eso está claro pero ¿a partir de aquí cómo lo gestionamos? En wordpress por ejemplo el gestor multimedia (no solo almacena imágenes) clasifica las carpetas por año y mes.

Usaría una librería ya existente. Se supone que queremos implementar una aplicación rolemaster, no crear un gestor de imágenes. Así el primer resultado que me sale al buscar "laravel carrierwave" es attachy.

En Rails tenemos librerías como Carrierwave o Laravel Paperclip que gestionan el almacenamiento automáticamente y que así te abstraen de cosas como:

La ruta Carrierwave la genera, por ejemplo, a partir de las siguientes propiedades:

Ejemplos de rutas en aplicaciones Ruby on Rails reales:


¿Debemos clasificar las imágenes en función del tipo de equipo? Si es armas, una carpeta llamada armas, otra para las imágenes de armaduras, etc

Inicialmente para levantar el MVP diría que sí. Que sean propiedades del mismo modelo, aunque se repitan o aunque haya que cargar dos veces lo mismo.

O se puede crear una entidad propia llamada Asset y luego hacer una asociación N..1 entre un Spell/Weapon/Item/Player y un Asset. El problema que veo inicialmente a este sistema es que eso tiene ciertas implicaciones en términos de UI que tienes que tener claro desde el primer momento que quieras hacer (ya tienes que hacer un CRUD de imágenes, y tienes que diseñar un selector de imágenes _à la WordPress). Pero si estás dispuesto a asumir esos retos de UI, se puede modelar así desde el principio si sospechas que evil_ogre.jpg te puede servir tanto para el Ogro de la campaña A como para el NPC de la campaña B.