none
como dibujar la formula de agua(H2O) utilizando Graphics.DrawString RRS feed

  • Pregunta

  • Hola a todos tengo una aplicacion que hace identificadores para personal de una x empresa...
    sucede que hay unos cambios que me propucieron y me piden unas letras en forma de formulas de química
    como H2O, CO2, etc...
    mi aplicacion utiliza Graphics.DrawString que e funciona super, pq ya rasteriza el texto o sea lo combierte en imagen y asi puedo integrarlo a otras imagenes que completan la credencial...
    alguien sabe como hacer esto.
    sábado, 25 de noviembre de 2017 15:59

Respuestas

  • Al parecer alguien ha editado el mensaje y borrado lo que había escrito al principio.

    Lo que había escrito Walter, si no recuerdo mal, era que se podía usar el símbolo Unicode para el subíndice 2 entre la H y la O. En la respuesta decía cuál era ese código, pero yo no me lo sé de memoria, así que propongo otra alternativa: jugar con el tamaño del Font y con las coordenadas del Drawstring para poner el H2O. Más o menos algo así:

    Font fontGrande = new Font("Arial", 12);
    Font fontPequeño = new Font("Arial", 7);
    Brush brocha = Brushes.Black;
    e.Graphics:DrawString("H", fontGrande, brocha, 10, 10);
    e.Graphics:DrawString("2", fontPequeño, brocha, 20, 15);
    e.Graphics:DrawString("O", fontGrande, brocha, 25, 10);
    

    Las coordenadas me las he inventado; tendrás que ajustarlas para que te quede cada carácter en el sitio correcto. Lo mismo con los tamaños de los Fonts: los he puesto al azar, ajústalos según te convenga.

    domingo, 3 de diciembre de 2017 18:50
    Moderador
  • Gracias a todos los que participaron en ayudar a solucionar o a dar luz en esta interrogante. Les cuento que he esprimido al maximo mi pequeño cerebro y di con esta solucion que creo que es la respuesta definitiva al tema.

    formulario:

    codigo:

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Drawing.Text;
    using System.Drawing.Drawing2D;
    
    namespace dibujarTextBox
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            float index = 0;    //saber cuanto se asciende o deciende el caracter.
            int elchar = 0;     //saber el caracter para que sea subIndice o SuperIndice.
    
            // cuando carga el valor del NumericUpDown llamado nudIndex
            private void nudIndex_ValueChanged(object sender, EventArgs e)
            {
                index = (float)nudIndex.Value;
            }
    
            // cuando carga el valor del NumericUpDown llamado nudChar
            private void nudChar_ValueChanged(object sender, EventArgs e)
            {
                elchar = (int)nudChar.Value;
            }
            
            private void textBox1_TextChanged(object sender, EventArgs e)
            {
                nudChar.Maximum = textBox1.TextLength-1;
            }        
    
            private void button3_Click(object sender, EventArgs e)
            {
                int IndexPlus = (int)index;
                // ponemos positivo para que aumente la altura del Resul
                if (IndexPlus < 0)
                {
                    IndexPlus = IndexPlus * -1; 
                }
                // para el indice en estado normal dibujo simple
                if (index == 0)
                {
                    Bitmap bm = new Bitmap(textBox1.TextLength * textBox1.Font.Height, textBox1.Font.Height);
                    Graphics g = Graphics.FromImage(bm);
                    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                    g.DrawString(textBox1.Text, textBox1.Font, Brushes.Black, new PointF(0, 0), StringFormat.GenericTypographic);
                    g.Dispose();
                    pictureBox1.Image = bm;
                }
    
                // para el indice cuando su posicion esta por encima o por debajo
                if (index != 0)
                {
                    // segmentacion del texto
                    Bitmap seg01;   
                    Bitmap seg02;
                    Bitmap seg03;
                    // imagen resultante de la union de todos los segmentos
                    Bitmap Resul;
                    
                    // para cuando el indice esta en el primer caracter
                    if (elchar == 0)
                    {
                        SizeF Sseg01 = dibujar(textBox1.Text.Substring(elchar, 1), textBox1.Font, out seg01);
                        SizeF Sseg02 = dibujar(textBox1.Text.Substring(elchar + 1), textBox1.Font, out seg02);
    
                        Resul = new Bitmap(seg01.Width + seg02.Width, Math.Max(seg01.Height, seg02.Height) + IndexPlus);
                        Graphics g = Graphics.FromImage(Resul);                    
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.DrawImage(seg01, 
                            new RectangleF(new PointF(0, 0),Sseg01), 
                            new RectangleF(new PointF(0, 0), Sseg01),
                            GraphicsUnit.Pixel);
                        g.DrawImage(seg02, 
                            new RectangleF(new PointF(Sseg01.Width, index), Sseg02),
                            new RectangleF(new PointF(0, 0), Sseg02), 
                            GraphicsUnit.Pixel);
                        g.Dispose();
                    }
                    else if (elchar == textBox1.TextLength-1)   // para cuando el indice esta en el ultimo caracter
                    {
                        SizeF Sseg01 = dibujar(textBox1.Text.Substring(0, elchar), textBox1.Font, out seg01);
                        SizeF Sseg02 = dibujar(textBox1.Text.Substring(elchar), textBox1.Font, out seg02);
    
                        Resul = new Bitmap(seg01.Width + seg02.Width, Math.Max(seg01.Height, seg02.Height) + IndexPlus);
                        Graphics g = Graphics.FromImage(Resul);
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.DrawImage(seg01,
                            new RectangleF(new PointF(0, index), Sseg01),
                            new RectangleF(new PointF(0, 0), Sseg01),
                            GraphicsUnit.Pixel);
                        g.DrawImage(seg02,
                            new RectangleF(new PointF(Sseg01.Width, 0), Sseg02),
                            new RectangleF(new PointF(0, 0), Sseg02),
                            GraphicsUnit.Pixel);
                        g.Dispose();
                    }
                    else    // para cuando el indice en cualquier parte de texto exepto las puntas 
                    {
                        SizeF Sseg01 = dibujar(textBox1.Text.Substring(0, elchar), textBox1.Font, out seg01);
                        SizeF Sseg02 = dibujar(textBox1.Text.Substring(elchar, 1), textBox1.Font, out seg02);
                        SizeF Sseg03 = dibujar(textBox1.Text.Substring(elchar + 1), textBox1.Font, out seg03);
    
                        int MaxHeight = Math.Max(seg01.Height, Math.Max(seg02.Height, seg03.Height)) + IndexPlus;
    
                        Resul = new Bitmap(seg01.Width + seg02.Width + seg03.Width, MaxHeight);
                        Graphics g = Graphics.FromImage(Resul);
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.SmoothingMode = SmoothingMode.AntiAlias;
    
                        g.DrawImage(seg01, 
                            new RectangleF(new PointF(0, index), Sseg01),
                            new RectangleF(new PointF(0, 0), Sseg01), 
                            GraphicsUnit.Pixel);
    
                        g.DrawImage(seg02, 
                            new RectangleF(new PointF(Sseg01.Width, 0), Sseg02),
                            new RectangleF(new PointF(0, 0), Sseg02), 
                            GraphicsUnit.Pixel);
    
                        g.DrawImage(seg03, 
                            new RectangleF(new PointF(Sseg01.Width + Sseg02.Width, index), Sseg03),
                            new RectangleF(new PointF(0, 0), Sseg03), 
                            GraphicsUnit.Pixel);                    
                        g.Dispose();
                    }
                    pictureBox1.Image = Resul;
                }
    
            }
            SizeF dibujar(string texto, Font fuente, out Bitmap MapadeBit)
            {
                SizeF Result;
                MapadeBit = new Bitmap(texto.Length * fuente.Height, fuente.Height);
                Graphics g = Graphics.FromImage(MapadeBit);
                g.TextRenderingHint = TextRenderingHint.AntiAlias;
                // para detectar si el texto termina con espacio o no
                if (texto[texto.Length - 1] == ' ')
                {
                    Result = g.MeasureString(texto, fuente, new PointF(0, 0), new StringFormat(StringFormatFlags.MeasureTrailingSpaces));
                    g.DrawString(texto, fuente, Brushes.Black, new PointF(0, 0), new StringFormat(StringFormatFlags.MeasureTrailingSpaces));
                }
                else
                {
                    Result = g.MeasureString(texto, fuente, new PointF(0, 0), StringFormat.GenericTypographic);
                    g.DrawString(texto, fuente, Brushes.Black, new PointF(0, 0), StringFormat.GenericTypographic);
                }
                g.Dispose();
    
                return Result;
            }
        }
    }
    

    • Marcado como respuesta cl2raul66 jueves, 5 de abril de 2018 15:09
    jueves, 5 de abril de 2018 15:09

Todas las respuestas



  • sábado, 25 de noviembre de 2017 16:19
  • no veo escrito nada, porfavor de una respuesta....
    domingo, 3 de diciembre de 2017 14:04
  • Al parecer alguien ha editado el mensaje y borrado lo que había escrito al principio.

    Lo que había escrito Walter, si no recuerdo mal, era que se podía usar el símbolo Unicode para el subíndice 2 entre la H y la O. En la respuesta decía cuál era ese código, pero yo no me lo sé de memoria, así que propongo otra alternativa: jugar con el tamaño del Font y con las coordenadas del Drawstring para poner el H2O. Más o menos algo así:

    Font fontGrande = new Font("Arial", 12);
    Font fontPequeño = new Font("Arial", 7);
    Brush brocha = Brushes.Black;
    e.Graphics:DrawString("H", fontGrande, brocha, 10, 10);
    e.Graphics:DrawString("2", fontPequeño, brocha, 20, 15);
    e.Graphics:DrawString("O", fontGrande, brocha, 25, 10);
    

    Las coordenadas me las he inventado; tendrás que ajustarlas para que te quede cada carácter en el sitio correcto. Lo mismo con los tamaños de los Fonts: los he puesto al azar, ajústalos según te convenga.

    domingo, 3 de diciembre de 2017 18:50
    Moderador
  • Quiero dar las gracias a todos los que han publicado en este tema, gracias por existir y ayudar...
    Aquí les traigo como logre hacerlo por si alguien lo necesita.

    file01:

    using System;
    using System.Text;
    
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace DesplazamientoVertical
    {
        class DespVertical
        {
            /// <summary>
            /// Texto que utilizaremos para convertirlo en imagen y para modificar su desplazamiento
            /// vertical.
            /// </summary>
            public string ElTexto { set; get; }
    
            /// <summary>
            /// Es la pocision de caracter seleccionado en el string para desplazarlo verticalmente.
            /// </summary>
            public int CharSeleccionado { set; get; }        
    
            /// <summary>
            /// Es el size de la imagen del medio en que se va a visualizar.
            /// </summary>
            public Size ImgBase { set; get; }
    
            /// <summary>
            /// Fuente que utilizara el texto cuando se convierta en imagen.
            /// </summary>
            public Font FuenteTexto { set; get; }
    
            /// <summary>
            /// Es el valor del desplazamiento.
            /// </summary>
            public int Desplazamiento { set; get; }
    
            Bitmap[] ImgsTexto;
    
            /// <summary>
            /// Optiene el size que ocupa cada caracter.
            /// </summary>
            /// <param name="miChar">Es el caracter en string.</param>
            /// <returns>Retorna el Size de miChar</returns>
            Size TamanioChar(string miChar)
            {
                Size SizeBmFondo = ImgBase;
                TextFormatFlags flags = (
                            TextFormatFlags.Default |
                            TextFormatFlags.PreserveGraphicsClipping |
                            TextFormatFlags.PreserveGraphicsTranslateTransform
                            );
                return TextRenderer.MeasureText(miChar, FuenteTexto, SizeBmFondo, flags);
            }
    
            /// <summary>
            /// Convierte cada caracter de la cadena ElTexto en un Bitmap y lo almacena en la matriz ImgsTexto.
            /// </summary>
            /// <returns>Retorna el tamaño total del todo el texto sumando imagen a imagen optenida.</returns>
            Size Char2ImgsTexto()
            {
                int ImgWidth = 0;
                int ImgHeight = 0;
                if (ImgsTexto != null)
                {
                    Array.Clear(ImgsTexto, 0, ImgsTexto.Length);
                }
                ImgsTexto = new Bitmap[ElTexto.Length];
                StringBuilder sb = new StringBuilder(ElTexto);
                for (int i = 0; i < ElTexto.Length; i++)
                {
                    string st = ElTexto[i].ToString();
                    Size s = TamanioChar(st);
                    ImgWidth = ImgWidth + s.Width;
                    if (s.Height > ImgHeight){ ImgHeight = s.Height; }
                    ImgsTexto[i] = new Bitmap(s.Width, s.Height);                
                    Graphics grp = Graphics.FromImage(ImgsTexto[i]);
                    SolidBrush brocha = new SolidBrush(Color.Black);
                    StringFormat drawFormat = new StringFormat();
                    grp.DrawString(st, FuenteTexto, brocha, 0, 0, drawFormat);
                    drawFormat.Dispose();
                    brocha.Dispose();
                    grp.Dispose();
                }
                Size Resul = new Size(ImgWidth, ImgHeight);
                return Resul;
            }
    
            /// <summary>
            /// Dibuja todas las imagenes optenidas en una sola.
            /// </summary>
            /// <param name="PosHeight">Es la posición vertical del caracter a modificar.</param>
            /// <returns>Retorna la imagen final.</returns>
            public Bitmap StingDraw(int PosHeight)
            {
                int Px = 0;
                int Py = 0;
                int i = 0;
                Size s = Char2ImgsTexto();
                int pH = 0;
                if (PosHeight < 0) { pH = PosHeight * -1; }
                else { pH = PosHeight; }
                s.Height = s.Height + pH;
                Bitmap bm = new Bitmap(s.Width, s.Height);
                Graphics grp = Graphics.FromImage(bm);
                foreach (var item in ImgsTexto)
                {               
                    Py = (s.Height / 2) - (item.Height / 2);
                    if (i == CharSeleccionado)
                    {
                        Py = (s.Height / 2) - (item.Height / 2) - PosHeight;
                    }                
                    grp.DrawImage(item, new Point(Px, Py));
                    Px = Px + item.Width;
                    i++;
                }            
                grp.Dispose();
                return bm;
            }
        }
    }
    

    file02

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace DesplazamientoVertical
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            DespVertical Dv;
    
            private void nudSelector_ValueChanged(object sender, EventArgs e)
            {
                Dv.CharSeleccionado = (int)nudSelector.Value;
            }
    
            private void nudDeplazador_ValueChanged(object sender, EventArgs e)
            {
                pbVisualizador.Image = Dv.StingDraw((int)nudDeplazador.Value);
            }
    
            private void tbTexto_KeyUp(object sender, KeyEventArgs e)
            {
                if (tbTexto.Text != "")
                {
                    bInsertar.Enabled = true;
                    nudSelector.Enabled = true;
                    nudDeplazador.Enabled = true;
                    Dv.ElTexto = tbTexto.Text;
                }
                else
                {
                    bInsertar.Enabled = false;
                    nudSelector.Enabled = false;
                    nudDeplazador.Enabled = false;
                }
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                Dv = new DespVertical();
                Dv.FuenteTexto = tbTexto.Font;
                Dv.ImgBase = pbVisualizador.Size;
                Dv.CharSeleccionado = (int)nudSelector.Value;
                nudDeplazador.Minimum = (pbVisualizador.Size.Width / 2) * -1;
                nudDeplazador.Maximum = (pbVisualizador.Size.Width / 2);
            }
    
            private void bInsertar_Click(object sender, EventArgs e)
            {
                nudSelector.Maximum = tbTexto.Text.Length - 1;
                pbVisualizador.Image = Dv.StingDraw((int)nudDeplazador.Value);
            }
        }
    }
    

    para tener en cuenta se realizo en VS2017.

    si alguien decea pulir y optimizar, se lo agradeceria mucho.

    lunes, 1 de enero de 2018 15:00
  • Una pequeña sugerencia para mejora:

    Fíjate en donde haces esto:

    SolidBrush brocha = new SolidBrush(Color.Black);

    y luego más abajo le haces un Dispose al Brush. Eso lo haces dentro de un bucle, por lo que a cada vuelta del bucle se crea y se destruye la brocha. Sería preferible crearla antes de entrar en el bucle y destruirla después de salir del mismo. O mejor todavía, utilizar Brushes.Black en lugar de new SolidBrush. Brushes.Black es una brocha creada estáticamente, por lo que no hay que destruirla después, y en consecuencia tiene mucho menos coste en tiempo de ejecución. Si solo lo hicieras una vez no tendría mucha importancia, pero teniendo en cuenta que lo haces dentro de un bucle es un detallito a tener en cuenta.

    martes, 2 de enero de 2018 9:20
    Moderador
  • Gracias Alberto Poblacion, por su consejo...
    pero algo no funciona bien, les dejo todo el codigo para que lo prueben...

    problema: escribo en el textbox "hola mundo" y presiono el boton "normal", el texto sale perfectamente como el control textBox; pero al presionar el boton "foro", el texto sale con gran separacion entre caracteres, alguien sabe por qué hace esto si yo sumo todos width de todas las imagenes de los caracteres y me retorna el sizer segun esto (ver: Char2ImgsTexto en la clase DespVertical).

    Gracias de antemano.

    formulario:

    fichero de clase agregado:

    using System;
    using System.Text;
    
    using System.Drawing;
    using System.Windows.Forms;
    using System.Drawing.Drawing2D;
    using System.Drawing.Text;
    
    namespace prueba
    {
        class DespVertical
        {
            /// <summary>
            /// Texto que utilizaremos para convertirlo en imagen y para modificar su desplazamiento
            /// vertical.
            /// </summary>
            public string ElTexto { set; get; }
    
            /// <summary>
            /// Es la pocision de caracter seleccionado en el string para desplazarlo verticalmente.
            /// </summary>
            public int CharSeleccionado { set; get; }
    
            /// <summary>
            /// Es el size de la imagen del medio en que se va a visualizar.
            /// </summary>
            public Size ImgBase { set; get; }
    
            /// <summary>
            /// Fuente que utilizara el texto cuando se convierta en imagen.
            /// </summary>
            public Font FuenteTexto { set; get; }
    
            /// <summary>
            /// Es el valor del desplazamiento.
            /// </summary>
            public int Desplazamiento { set; get; }
    
            Bitmap[] ImgsTexto;
    
            /// <summary>
            /// Optiene el size que ocupa cada caracter.
            /// </summary>
            /// <param name="miChar">Es el caracter en string.</param>
            /// <returns>Retorna el Size de miChar</returns>
            Size TamanioChar(string miChar)
            {
                Size SizeBmFondo = ImgBase;
                TextFormatFlags flags = (
                            TextFormatFlags.Default |
                            TextFormatFlags.PreserveGraphicsClipping |
                            TextFormatFlags.PreserveGraphicsTranslateTransform
                            );
                return TextRenderer.MeasureText(miChar, FuenteTexto, SizeBmFondo, flags);
            }
    
            /// <summary>
            /// Convierte cada caracter de la cadena ElTexto en un Bitmap y lo almacena en la matriz ImgsTexto.
            /// </summary>
            /// <returns>Retorna el tamaño total del todo el texto sumando imagen a imagen optenida.</returns>
            Size Char2ImgsTexto()
            {
                int ImgWidth = 0;
                int ImgHeight = 0;
                if (ImgsTexto != null)
                {
                    Array.Clear(ImgsTexto, 0, ImgsTexto.Length);
                }
                ImgsTexto = new Bitmap[ElTexto.Length];
                StringBuilder sb = new StringBuilder(ElTexto);
                for (int i = 0; i < ElTexto.Length; i++)
                {
                    string st = ElTexto[i].ToString();
                    Size s = TamanioChar(st);
                    ImgWidth = ImgWidth + s.Width;
                    if (s.Height > ImgHeight) { ImgHeight = s.Height; }
                    ImgsTexto[i] = new Bitmap(s.Width, s.Height);
                    Graphics grp = Graphics.FromImage(ImgsTexto[i]);
                    //SolidBrush brocha = new SolidBrush(Color.Black);
                    StringFormat drawFormat = new StringFormat();
                    grp.SmoothingMode = SmoothingMode.AntiAlias;
                    grp.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    grp.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    grp.TextRenderingHint = TextRenderingHint.AntiAlias;
                    grp.DrawString(st, FuenteTexto, Brushes.Black, 0, 0, drawFormat);
                    drawFormat.Dispose();
                    //brocha.Dispose();
                    grp.Dispose();
                }
                Size Resul = new Size(ImgWidth, ImgHeight);
                return Resul;
            }
    
            /// <summary>
            /// Dibuja todas las imagenes optenidas en una sola.
            /// </summary>
            /// <param name="PosHeight">Es la posición vertical del caracter a modificar.</param>
            /// <returns>Retorna la imagen final.</returns>
            public Bitmap StingDraw(int PosHeight)
            {
                int Px = 0;
                int Py = 0;
                int i = 0;
                Size s = Char2ImgsTexto();
                int pH = 0;
                if (PosHeight < 0) { pH = PosHeight * -1; }
                else { pH = PosHeight; }
                s.Height = s.Height + pH;
                Bitmap bm = new Bitmap(s.Width, s.Height);
                Graphics grp = Graphics.FromImage(bm);
                foreach (var item in ImgsTexto)
                {
                    Py = (s.Height / 2) - (item.Height / 2);
                    if (i == CharSeleccionado)
                    {
                        Py = (s.Height / 2) - (item.Height / 2) - PosHeight;
                    }
                    grp.DrawImage(item, new Point(Px, Py));
                    Px = Px + item.Width;
                    i++;
                }
                grp.Dispose();
                return bm;
            }
        }
        
    }
    

    fichero del form1:

    using System;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Text;
    using System.Windows.Forms;
    
    
    namespace prueba
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            Size BmTextoSize;
            Bitmap BmTexto;
    
            DespVertical Dv;
    
            void BmTexto_Size()
            {
                Size SizeBmFondo = new Size(400, 200);
                TextFormatFlags flags = (
                            TextFormatFlags.Default |
                            TextFormatFlags.PreserveGraphicsClipping |
                            TextFormatFlags.PreserveGraphicsTranslateTransform
                            );
                BmTextoSize = TextRenderer.MeasureText(tbTexto.Text, tbTexto.Font, SizeBmFondo, flags);
    
                if ((BmTextoSize.Width < pbSalida.Size.Width) && (BmTextoSize.Height < pbSalida.Size.Height))
                {
                    BmTexto = new Bitmap(BmTextoSize.Width, BmTextoSize.Height);
                }
                else
                {
                    BmTexto_Size();
                }
            }
    
            private void bNormal_Click(object sender, EventArgs e)
            {
                BmTexto_Size();
                Bitmap Resul = new Bitmap(BmTexto);
                
                Graphics grp = Graphics.FromImage(Resul);
    
                
                StringFormat drawFormat = new StringFormat();
                grp.SmoothingMode = SmoothingMode.AntiAlias;
                grp.InterpolationMode = InterpolationMode.HighQualityBicubic;
                grp.PixelOffsetMode = PixelOffsetMode.HighQuality;
                grp.TextRenderingHint = TextRenderingHint.AntiAlias;
    
                grp.DrawString(tbTexto.Text, tbTexto.Font, Brushes.Black, 0, 0, drawFormat);
                
                drawFormat.Dispose();
                grp.Dispose();
    
                pbSalida.Image = Resul;
            }
    
            private void bForo_Click(object sender, EventArgs e)
            {        
    
                Dv = new DespVertical();
                Dv.ElTexto = tbTexto.Text;
                Dv.FuenteTexto = tbTexto.Font;
                Dv.ImgBase = pbSalida.Size;
                Dv.CharSeleccionado = (int)nudSelector.Value;
    
                nudSelector.Maximum = tbTexto.Text.Length - 1;
                pbSalida.Image = Dv.StingDraw((int)nudDeplazador.Value);
            }
    
            private void nudDeplazador_ValueChanged(object sender, EventArgs e)
            {
                nudDeplazador.Minimum = (pbSalida.Size.Width / 2) * -1;
                nudDeplazador.Maximum = (pbSalida.Size.Width / 2);
            }
    
            private void tbTexto_TextChanged(object sender, EventArgs e)
            {
                nudSelector.Maximum = tbTexto.Text.Length - 1;
            }
        }
    }
    

    jueves, 15 de febrero de 2018 18:07
  • parece q a mucha gente no le intereza este tema, yo seguire compartiendo mis avances apesar de la falta de colaboracion capacitada...
    no se el pq de mi ultima mejora, pero les traigo la mejora y menos codigo...
    formulario:

    codigo:

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Drawing.Text;
    using System.Drawing.Drawing2D;
    
    namespace dibujarTextBox
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            float index = 0;    //saber cuanto se asciende o deciende el caracter.
            int elchar = 0;     //saber el caracter para que sea subIndice o SuperIndice.
    
            void dibujar()
            {
                int cont = 0;
                float Y = index;
                Bitmap bm = new Bitmap(textBox1.Width, textBox1.Height * 2);
                Graphics g = Graphics.FromImage(bm);            
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.InterpolationMode = InterpolationMode.High;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
    
                float posX = 0; float posY = 0; 
                foreach (var item in textBox1.Text)
                {
                    SizeF s = g.MeasureString(item.ToString(), textBox1.Font, new PointF(0, 0), StringFormat.GenericTypographic);
                    if (s.Width < 0)
                    {
                        s = new SizeF((s.Width * -1), s.Height);
                    }
                    if (Y < 0)
                    {
                        Y = Y * -1;
                    }
                    
                    if (elchar == cont && index != 0)
                    {
                        if (index < 0)
                        {
                            g.DrawString(item.ToString(), textBox1.Font, Brushes.Black, new RectangleF(new PointF(posX, posY + Y*Y), s), StringFormat.GenericTypographic);
                        }
                        if (index > 0)
                        {
                            g.DrawString(item.ToString(), textBox1.Font, Brushes.Black, new RectangleF(new PointF(posX, posY - Y), s), StringFormat.GenericTypographic);
                        }
                    }
                    else
                    {
                        g.DrawString(item.ToString(), textBox1.Font, Brushes.Black, new RectangleF(new PointF(posX, posY + Y), s), StringFormat.GenericTypographic);
                    }
                    
                    posX = posX + s.Width;
                    cont++;
                }            
                g.Dispose();
    
                pictureBox1.Image = bm;
            }
    
            // cuando carga el valor del NumericUpDown llamado nudIndex
            private void nudIndex_ValueChanged(object sender, EventArgs e)
            {
                index = (float)nudIndex.Value;
            }
            private void button1_Click(object sender, EventArgs e)
            {
                dibujar();
            }
    
            // cuando carga el valor del NumericUpDown llamado nudChar
            private void nudChar_ValueChanged(object sender, EventArgs e)
            {
                elchar = (int)nudChar.Value;
            }
            
            private void textBox1_TextChanged(object sender, EventArgs e)
            {
                nudChar.Maximum = textBox1.TextLength;
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                dibujar2();
            }
    
            void dibujar2()
            {
                Bitmap bm = new Bitmap(textBox1.Width, textBox1.Height * 2);
                Graphics g = Graphics.FromImage(bm);
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.InterpolationMode = InterpolationMode.High;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
    
                SizeF s = g.MeasureString(textBox1.Text, textBox1.Font, new PointF(0, 0), StringFormat.GenericTypographic);
                g.DrawString(textBox1.Text, textBox1.Font, Brushes.Black, new RectangleF(new PointF(0, 0), s), StringFormat.GenericTypographic);
                
                g.Dispose();
    
                pictureBox1.Image = bm;
            }
        }
    }
    


    Nota:
    -el primer NumericUpDown del formulario es para cuanto subimos o bajamos el caracter.
    -el segundo NumericUpDown del formulario es para seleccionar el caracter contando desde 0.
    -el boton llamado mostrar es el que muestra el resultado del subIndice o superIndice.
    -el boton todo es para mostrar todo el texto sin indice ni subIndice, ni superIndice.

    todo marchaba bien hasta que quise darle espacios al texto, ejemplo:

    escribimos { hola mundo } y damos
    click con [mostrar] y nos muestra { holam undo }
    click con [todo] y nos muestra { hola mundo }

    y no se pq hace esto, alguien quien pueda ayudar...

    viernes, 23 de marzo de 2018 14:45
  • Gracias a todos los que participaron en ayudar a solucionar o a dar luz en esta interrogante. Les cuento que he esprimido al maximo mi pequeño cerebro y di con esta solucion que creo que es la respuesta definitiva al tema.

    formulario:

    codigo:

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Drawing.Text;
    using System.Drawing.Drawing2D;
    
    namespace dibujarTextBox
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            float index = 0;    //saber cuanto se asciende o deciende el caracter.
            int elchar = 0;     //saber el caracter para que sea subIndice o SuperIndice.
    
            // cuando carga el valor del NumericUpDown llamado nudIndex
            private void nudIndex_ValueChanged(object sender, EventArgs e)
            {
                index = (float)nudIndex.Value;
            }
    
            // cuando carga el valor del NumericUpDown llamado nudChar
            private void nudChar_ValueChanged(object sender, EventArgs e)
            {
                elchar = (int)nudChar.Value;
            }
            
            private void textBox1_TextChanged(object sender, EventArgs e)
            {
                nudChar.Maximum = textBox1.TextLength-1;
            }        
    
            private void button3_Click(object sender, EventArgs e)
            {
                int IndexPlus = (int)index;
                // ponemos positivo para que aumente la altura del Resul
                if (IndexPlus < 0)
                {
                    IndexPlus = IndexPlus * -1; 
                }
                // para el indice en estado normal dibujo simple
                if (index == 0)
                {
                    Bitmap bm = new Bitmap(textBox1.TextLength * textBox1.Font.Height, textBox1.Font.Height);
                    Graphics g = Graphics.FromImage(bm);
                    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                    g.DrawString(textBox1.Text, textBox1.Font, Brushes.Black, new PointF(0, 0), StringFormat.GenericTypographic);
                    g.Dispose();
                    pictureBox1.Image = bm;
                }
    
                // para el indice cuando su posicion esta por encima o por debajo
                if (index != 0)
                {
                    // segmentacion del texto
                    Bitmap seg01;   
                    Bitmap seg02;
                    Bitmap seg03;
                    // imagen resultante de la union de todos los segmentos
                    Bitmap Resul;
                    
                    // para cuando el indice esta en el primer caracter
                    if (elchar == 0)
                    {
                        SizeF Sseg01 = dibujar(textBox1.Text.Substring(elchar, 1), textBox1.Font, out seg01);
                        SizeF Sseg02 = dibujar(textBox1.Text.Substring(elchar + 1), textBox1.Font, out seg02);
    
                        Resul = new Bitmap(seg01.Width + seg02.Width, Math.Max(seg01.Height, seg02.Height) + IndexPlus);
                        Graphics g = Graphics.FromImage(Resul);                    
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.DrawImage(seg01, 
                            new RectangleF(new PointF(0, 0),Sseg01), 
                            new RectangleF(new PointF(0, 0), Sseg01),
                            GraphicsUnit.Pixel);
                        g.DrawImage(seg02, 
                            new RectangleF(new PointF(Sseg01.Width, index), Sseg02),
                            new RectangleF(new PointF(0, 0), Sseg02), 
                            GraphicsUnit.Pixel);
                        g.Dispose();
                    }
                    else if (elchar == textBox1.TextLength-1)   // para cuando el indice esta en el ultimo caracter
                    {
                        SizeF Sseg01 = dibujar(textBox1.Text.Substring(0, elchar), textBox1.Font, out seg01);
                        SizeF Sseg02 = dibujar(textBox1.Text.Substring(elchar), textBox1.Font, out seg02);
    
                        Resul = new Bitmap(seg01.Width + seg02.Width, Math.Max(seg01.Height, seg02.Height) + IndexPlus);
                        Graphics g = Graphics.FromImage(Resul);
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.DrawImage(seg01,
                            new RectangleF(new PointF(0, index), Sseg01),
                            new RectangleF(new PointF(0, 0), Sseg01),
                            GraphicsUnit.Pixel);
                        g.DrawImage(seg02,
                            new RectangleF(new PointF(Sseg01.Width, 0), Sseg02),
                            new RectangleF(new PointF(0, 0), Sseg02),
                            GraphicsUnit.Pixel);
                        g.Dispose();
                    }
                    else    // para cuando el indice en cualquier parte de texto exepto las puntas 
                    {
                        SizeF Sseg01 = dibujar(textBox1.Text.Substring(0, elchar), textBox1.Font, out seg01);
                        SizeF Sseg02 = dibujar(textBox1.Text.Substring(elchar, 1), textBox1.Font, out seg02);
                        SizeF Sseg03 = dibujar(textBox1.Text.Substring(elchar + 1), textBox1.Font, out seg03);
    
                        int MaxHeight = Math.Max(seg01.Height, Math.Max(seg02.Height, seg03.Height)) + IndexPlus;
    
                        Resul = new Bitmap(seg01.Width + seg02.Width + seg03.Width, MaxHeight);
                        Graphics g = Graphics.FromImage(Resul);
                        g.CompositingQuality = CompositingQuality.HighQuality;
                        g.SmoothingMode = SmoothingMode.AntiAlias;
    
                        g.DrawImage(seg01, 
                            new RectangleF(new PointF(0, index), Sseg01),
                            new RectangleF(new PointF(0, 0), Sseg01), 
                            GraphicsUnit.Pixel);
    
                        g.DrawImage(seg02, 
                            new RectangleF(new PointF(Sseg01.Width, 0), Sseg02),
                            new RectangleF(new PointF(0, 0), Sseg02), 
                            GraphicsUnit.Pixel);
    
                        g.DrawImage(seg03, 
                            new RectangleF(new PointF(Sseg01.Width + Sseg02.Width, index), Sseg03),
                            new RectangleF(new PointF(0, 0), Sseg03), 
                            GraphicsUnit.Pixel);                    
                        g.Dispose();
                    }
                    pictureBox1.Image = Resul;
                }
    
            }
            SizeF dibujar(string texto, Font fuente, out Bitmap MapadeBit)
            {
                SizeF Result;
                MapadeBit = new Bitmap(texto.Length * fuente.Height, fuente.Height);
                Graphics g = Graphics.FromImage(MapadeBit);
                g.TextRenderingHint = TextRenderingHint.AntiAlias;
                // para detectar si el texto termina con espacio o no
                if (texto[texto.Length - 1] == ' ')
                {
                    Result = g.MeasureString(texto, fuente, new PointF(0, 0), new StringFormat(StringFormatFlags.MeasureTrailingSpaces));
                    g.DrawString(texto, fuente, Brushes.Black, new PointF(0, 0), new StringFormat(StringFormatFlags.MeasureTrailingSpaces));
                }
                else
                {
                    Result = g.MeasureString(texto, fuente, new PointF(0, 0), StringFormat.GenericTypographic);
                    g.DrawString(texto, fuente, Brushes.Black, new PointF(0, 0), StringFormat.GenericTypographic);
                }
                g.Dispose();
    
                return Result;
            }
        }
    }
    

    • Marcado como respuesta cl2raul66 jueves, 5 de abril de 2018 15:09
    jueves, 5 de abril de 2018 15:09