/// <summary>
		/// Este metodo efectua el escalado de la imagen.
		/// </summary>
		/// <param name="image">La imagen que queremos escalar.</param>
		/// <returns>La imagen escalada al tamaño establecido.</returns>
		public override FloatBitmap Apply(FloatBitmap image) 
		{
			Pixbuf pb = image.CreatePixbuf();
				
			pb = pb.ScaleSimple(normalizedSize, normalizedSize, InterpType.Bilinear);
			
			return FloatBitmap.CreateFromPixbuf(pb);
		}
		private void OnUnassistedProcessBtnClicked(object sender, EventArgs args)
		{
			// We try to free memory.
			GC.Collect();
			segmentationStore.Clear();
			
			
			MainRecognizerWindow.ProcessItemsSensitive = true;
			unassistedControlHBB.Sensitive = false;
			unassistedTaskNameLabel.Text = "Segmentación y OCR";
			
			unassistedGlobalProgressBar.Fraction = 0;
			
			// We create the image to be recognized.
			
			Bitmap  bitmap = handwritingArea.Bitmap;
			
			FloatBitmap floatBitmap = 
				new FloatBitmap(bitmap.Width, bitmap.Height);
			
			for(int i=0; i< bitmap.Width; i++)
			{
				for(int j = 0; j < bitmap.Height; j++)
				{
					floatBitmap[i,j] = bitmap.GetPixel(i,j).GetBrightness();
				}
			}
			
			// The original image is set.
			originalImage = floatBitmap.CreatePixbuf();
			
			MathTextBitmap mtb = new MathTextBitmap(originalImage);
			
			SegmentedNode node = new SegmentedNode("Raíz",
			                                       mtb,
			                                       null);
			    
			segmentationStore.AddNode(node);
			
			ocrController.StartNode = node;
			ocrController.SearchDatabase = false;
			ocrController.Databases =  
				Config.RecognizerConfig.Instance.Databases;
			ocrController.Next(ControllerStepMode.UntilEnd);
		}
		/// <summary>
		/// Creates a bitmap out of a projection
		/// </summary>
		/// <param name="projection">
		/// The projection <see cref="BitmapProjection"/>
		/// </param>
		/// <returns>
		/// A <see cref="Pixbuf"/> with the projection graphical representation.
		/// </returns>
		public static Pixbuf CreateProjectionBitmap(BitmapProjection projection)
		{
			int max=-1;
			foreach(int i in projection.Values)
			{
				if(max<i)
				{
					max=i;
				}		
			}

			FloatBitmap bitmap = new FloatBitmap(projection.Values.Length, 
			                                     max);
			
			
			for(int k=0;k<projection.Values.Length;k++)
			{
				Console.WriteLine(projection.Values[k]);
				for(int j = 0; j< projection.Values[k];j++)
				{
				
					bitmap[k,j] = FloatBitmap.Black;
				}
			}		
			
			return bitmap.CreatePixbuf();
		}
		private List<MathTextBitmap> WaterfallSegment(MathTextBitmap bitmap)
		{
			FloatBitmap image = Rotate(bitmap.FloatImage);
			
			if(reflection)
			{
				image = Reflect(image);
			}
			
			
			// Buscamos un pixel blanco en el que empezar.
					
			List<Point> points = new List<Point>();
			
			// Aqui vamos a pintar la linea que divide las dos partes de la imagen.
			FloatBitmap cutImage = new FloatBitmap(image.Width,image.Height);
			
			// Buscamos por filas, desde abajo, para encontrar el primer pixel 
			// negro mas cercano a la esquina (0,0).
			int i,j,k;
			
			if(search)
			
			{
				bool startFound = false;
				for(j=0; j<image.Height && !startFound; j++)
				{
					for(i=0; i<image.Width && !startFound;i++)
					{
						
						if(image[i,j] != FloatBitmap.White)
						{
							for(k=0; k<j ;k++)
							{
								// Añadimos a la lista de puntos los puntos 
								// entre el borde inferior y el punto en la fila
								// inmediatamente inferior a la del punto negro.
								
								points.Add(new Point(i,k));
								cutImage[i,k] = FloatBitmap.Black;
							}						
							startFound = true;
						}					
					}
				}
			}
			else
			{
				points.Add(new Point(image.Width/2, 0));
				cutImage[image.Width/2,0] = FloatBitmap.Black;
			}
			
			
			if(points.Count ==0)
			{
				return new List<MathTextBitmap>();
			}
			
			int x = points[0].X;
			int y = points[0].Y;
				
			bool newPoints = true;
			bool borderFound = false;
			while(newPoints && !borderFound)
			{
				if(x == image.Width -1
				   || y == image.Height -1)
				{					
					borderFound = true;
				}
				else
				{
					// Aqui almacenamos los posibles vectores..
					int [] vectors = new int[]{0,1, 1,1, 1,0,  -1,0, -1,1, -1,-1, 0,-1};
						
					bool notNewFound = true;
					for ( k = 0; k < vectors.Length && notNewFound; k+=2)
					{
						
						int xd = vectors[k];
						int yd = vectors[k+1];
						// Vamos comprobando los casos
						// Tenemos que:
						// · No salirnos de los limites
						// · El pixel ha de ser blanco.
						// . No puede ser el anterior del actual, para no meternos
						//   en un bucle.	
						if(x + xd >= 0
						   && y + yd >= 0
						   && x + xd < image.Width
						   && y + yd < image.Height
						   && image[x+ xd, y+yd] == FloatBitmap.White
						   && !points.Contains(new Point(x +xd, y +yd)))
							
						{
							x = x +xd;
							y = y + yd;
							points.Add(new Point(x,y));
							cutImage[x,y]= FloatBitmap.Black;
							
							// Indicamos que hemos encontrado el valor.
							notNewFound = false;
						}
					}
					
					newPoints = !notNewFound;
					
				}
			}
			
			List<MathTextBitmap> children = new List<MathTextBitmap>();
			
			// Hemos encontrado el borde, cortamos la imagen.
			if(borderFound)
			{
				
				// Primero encontramos un punto blanco.
				bool whiteFound = false;
				int x0 = 0, y0 = 0;
				for(i = 0; i < cutImage.Width && !whiteFound; i++)
				{
					for(j = 0; j< cutImage.Height && !whiteFound; j++)
					{
						if(cutImage[i,j] != FloatBitmap.Black)
						{
							// Mas que el primer blaco, buscamos el primer
							// negro;
							whiteFound = true;
							x0 = i;
							y0 = j;							
						}
					}
				}
				
				if(reflection)
					cutImage = Reflect(cutImage);
				
				// Tenemos que rotar la imagen de corte para alinearla con la orginal.				
				cutImage = UndoRotate(cutImage);

				
				// Rellenamos la imagen de negro a partir del punto encontrado.
				cutImage.Fill(x0, y0, FloatBitmap.Black);
				
#if DEBUG			
				string path = System.IO.Path.GetTempFileName();
				cutImage.CreatePixbuf().Save(String.Format(path+"_{0}_{1}.png", mode, reflection), "png");
#endif				
				
				// Recorremos la imagen de corte, y sacamos dos imagenes;
				FloatBitmap res1 = new FloatBitmap(cutImage.Width, cutImage.Height);
				FloatBitmap res2 = new FloatBitmap(cutImage.Width, cutImage.Height);
				

				
				FloatBitmap origImage = bitmap.FloatImage;
				bool res1HasBlack = false;
				bool res2HasBlack = false;
				
				for(i=0; i < cutImage.Width; i++)
				{
					for(j = 0; j< cutImage.Height; j++)
					{
						// Si estamos en la zona negra de la imagen de corte,
						// copiamos en la primera imagen de resultado,
						// y sino, en la segunda.
						if(cutImage[i, j] == FloatBitmap.Black)
						{
							res1[i,j] = origImage[i,j];
							if (origImage[i,j]!=FloatBitmap.White)
							{
								res1HasBlack = true;
							}
						}
						else
						{
							res2[i,j] = origImage[i,j]; 
							if (origImage[i,j]!=FloatBitmap.White)
							{
								res2HasBlack = true;
							}
						}
					}
				}
				

				
				// Si las dos imágenes tienen pixeles negros, hemos separado la
				// imagen correctamente, sino, solo hemos rodeado algo
				// que no fuimos capaces de segmentar.
				// Si no, no segmenatamos nada, se devolverá la lista vacia.
				if(res1HasBlack && res2HasBlack)
				{
					Gdk.Point pd;
					Gdk.Size sd;					
					GetEdges(res1, out pd, out sd);		
					res1 = res1.SubImage(pd.X,pd.Y,sd.Width, sd.Height);
					children.Add(new MathTextBitmap(res1, 
					                                new Gdk.Point(bitmap.Position.X+pd.X,
					                                              bitmap.Position.Y+pd.Y)));
					
					GetEdges(res2, out pd, out sd);		
					res2 = res2.SubImage(pd.X,pd.Y,sd.Width, sd.Height);
					children.Add(new MathTextBitmap(res2, 
					                                new Gdk.Point(bitmap.Position.X+pd.X,
					                                              bitmap.Position.Y+pd.Y)));

				}	

			}
			
			return children;
			
		}