/// <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()); }
/// <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 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); }