viernes, 2 de enero de 2015

Crear mosaicos de imágenes en C#

Hoy voy a subir una pequeña aplicación para crear mosaicos de imágenes. La idea viene a partir de esta entrada http://la-morsa.blogspot.com.es/2007/11/fotomorsaicos.html, del blog La_Morsa.
He creado una biblioteca de clases llamada MosaicosBiblioteca.dll, con la cual, a partir de una imagen y una lista de imágenes, se creará el mosaico.
Primeramente os voy a mostrar un vídeo de la aplicación. No obstante, hay que tener en cuenta que mi lista de imágenes consta de tan sólo 33 imágenes, cuando para que quedase bien la imagen-mosaico resultante, quizá deberían haber hecho falta 1000 imágenes por lo menos.




Ahora os voy a explicar un poco cómo funciona la biblioteca de clases (la podéis descargar desde aquí). Vamos a crear un proyecto nuevo, le llamaremos "EjemploFacilMosaicos", y vamos a añadir la referencia a la biblioteca de clases, tal y como muestra la imagen.

Agregar referencia a proyecto

Buscar referencia

A continuación, en el formulario principal de la aplicación, vamos a añadir dos Picturebox y tres botones.
Formulario principal
Añadimos el siguiente código fuente:
       
public partial class Form1 : Form
    {
        private List listImages;

        public Form1()
        {
            InitializeComponent();
         }

        private void openImage()
        {
            Bitmap bmp = MosaicosBiblioteca.Mosaics.ImageIO.openImage();
            pictureBox1.Image = (bmp != null) ? bmp : pictureBox1.Image;
        }
        private void seleccionarImagenes()
        {
            var rutaImagenes = MosaicosBiblioteca.Mosaics.ImageIO.openFolder();
            if(!string.IsNullOrEmpty(rutaImagenes))
            {
                this.listImages = MosaicosBiblioteca.Mosaics.ImageIO.openImages(rutaImagenes, new Size(20, 20));
            }
        }
        private void crearMosaico()
        {
            if(this.listImages!=null && this.listImages.Count()>0)
            {
                MosaicosBiblioteca.Mosaics.Mosaic mosaic = new MosaicosBiblioteca.Mosaics.Mosaic((Bitmap)pictureBox1.Image,this.listImages,40,40,
                    new MosaicosBiblioteca.Mosaics.Compare.Normal(),new MosaicosBiblioteca.Mosaics.Average.Mean(),new MosaicosBiblioteca.Mosaics.CreateImage.Weighted(0.5,0.5));
                pictureBox2.Image=mosaic.createMosaic();
                
             }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            seleccionarImagenes();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            crearMosaico();
        }
        private void button3_Click(object sender, EventArgs e)
        {
            openImage();
        }
    }

Ejecutamos y ya podemos crear mosaicos.
Mosaico creado

Vamos a detallar un poco más el constructor de la clase Mosaic, que es donde está el asunto.
En el constructor, le tenemos que pasar 7 parámetros:
  1. imgOriginal (Bitmap): imagen original que será la base del mosaico. 
  2. imgsMosaic (List<Bitmap>): lista de imágenes que compondrán la imagen-mosaico.
  3. numberDivisionsHor (int): número de divisiones horizontales que tendrá la imagen-mosaico.
  4. numberDivisionVer (int): número de divisiones verticales que tendrá la imagen-mosaico.
  5. compare (ICompare): es un objeto que respete la interfaz ICompare, y decidirá al crear el mosaico si alguna de las imágenes puede o no repetirse. Por ejemplo, si no se puede repetir la imágenes situada a la izquierda con respecto a cada celda del mosaico (new MosaicosBiblioteca.Mosaics.Compare.NoLeft()).
  6. average (IAverage): es un objeto que respete la interfaz IAverage, y será quien calcule la media de la lista de imágenes y la imagen original, previo a la asignación de imágenes. Por ejemplo, puede calcular la moda (new MosaicosBiblioteca.Mosaics.Average.Mean()).
  7. createImage (ICreateImage): es un objeto que respete la interfaz ICreateImage, y decidirá, en la imagen de salida, si se hace algún tipo de ajuste a la lista de imágenes seleccionadas para el mosaico. Por ejemplo, se puede hacer un ajuste del 50% entre la imagen seleccionada, y el color medio de dicha zona (new MosaicosBiblioteca.Mosaics.CreateImage.Weighted(0.5,0.5)).
Una vez creado el constructor, llama a la función createMosaic que devolverá el mosaico creado.
El programa completo, biblioteca de clases y ejemplo fácil, lo podéis descargar desde aquí:

1 comentario: