Cuando la representación de texto en un mapa de bits, me parece que el texto se ve muy mal cuando se representan en la parte superior de una zona de no-opaco alfa. El problema es cada vez peor, ya que los píxeles subyacentes a ser más transparentes. Si tuviera que adivinar, yo diría que cuando los píxeles subyacentes son transparentes, el texto representador de los sorteos de cualquier anti-alias ‘gris’ los píxeles de color negro sólido.

Aquí hay algunas capturas de pantalla:

Texto dibujado en la parte superior de los píxeles transparentes:

Mala representación de texto utilizando el Lazo en la parte superior de los píxeles transparentes

Texto dibujado en la parte superior de píxeles semitransparentes:

Mala representación de texto utilizando el Lazo en la parte superior de los píxeles transparentes

Texto dibujado en los píxeles opacos:

Mala representación de texto utilizando el Lazo en la parte superior de los píxeles transparentes

Aquí está el código que se usa para representar el texto:

g.SmoothingMode = SmoothingMode.HighQuality;
g.DrawString("Press the spacebar", Font, Brushes.Black, textLeft, textTop);
  • Creo que el resultado dependerá también si ClearType está habilitado o no.
  • Se ve que no son la «limpieza» (o más bien invalidar) el fondo transparente.
  • cualquier solución final con el código fuente completo ?
  • Eres capaz de subir las imágenes que incluye Desbordamiento de la Pila? No van a disminuir a partir de Dropbox ya.
InformationsquelleAutor mackenir | 2010-06-07

4 Comentarios

  1. 28

    La opción que he usado para solucionar este problema fue:

    Graphics graphics = new Graphics();
    graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;

    Hay algunas otras opciones útiles en TextRenderingHint

    Espero que ayude

    • Intercambia respuesta para esto, a pesar de que esta es una muy vieja pregunta y no he probado esta respuesta.
    • user3470185 la respuesta (g.TextRenderingHint = Dibujo.Texto.TextRenderingHint.AntiAliasGridFit) produce un mejor resultado.
  2. 16

    Hay una respuesta muy simple a este…

    g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit

    Si establece este antes de procesar el texto, se va a salir claro. Además, este método es compatible con más tamaños de fuente (de forma predeterminada, sólo va hasta la talla 56).

    Gracias por leer este post.

  3. 12

    De la primera salida, es lo que usted consigue cuando usted dibuja el texto negro sobre un fondo negro, probablemente de Color.Transparente. La 2ª fue dibujado en un casi-negro de fondo. El 3º fue dibujado en el mismo fondo que está siendo mostrado.

    Anti-aliasing no puede funcionar cuando sobre un fondo transparente. Los colores utilizados para el anti-aliasing de píxeles no se mezcla la carta de la forma en el fondo, cuando se muestra el texto con un fondo diferente. Los píxeles se convertirá ahora en muy notable y que el texto parezca muy malo.

    Nota que SmoothingMode no afecta a la salida de texto. Se verá un poco menos malo si utiliza una menor calidad TextRenderingHint y un fondo de un color grisáceo con un alfa de cero. Sólo TextRenderingHint.SingleBitPerPixelGridFit evita todos los anti-aliasing problemas.

    Conseguir una solución perfecta para esto es muy difícil. Vista del efecto de cristal en la ventana de la barra de título de usos muy sutil sombreado para dar al texto un bien se define el color de fondo. Tendría SysInternals’ ZoomIt herramienta para verlo realmente. DrawThemeTextEx función() con un valor distinto de cero iGlowSize.

    • Ugh. Supongo que me podría dibujar el texto en negro sobre blanco en un mapa de bits temporal, convertir a blanco a transparente, y gris semi-transparente de color negro, a continuación, dibuje este para el final de mapa de bits. Voy a tratar diferentes TextRenderingHints. De lo contrario, creo que el efecto parcial de la transparencia de fondo no es demasiado malo. Una cosa, aunque – en cada caso, el fondo es del mismo color (blanco) con diferentes transparencia, por lo que me molestaría esperar de texto a dibujar como este con un ‘efectiva’ color de fondo de negro.
    • No estoy seguro de lo que quieres decir. Problema clave es la GDI no puede ver la transparencia, se ve el valor RGB del color transparente. Color.Transparente es una muy mala elección, su valor RGB es cero. Negro.
    • Lo que quiero decir es que el fondo está pintado con blanco, con un componente alfa. No está seguro de que usted tiene Color.Transparente de.
    • Eeasy, tigre 🙂
    • sí, es una responsabilidad común para las personas que pasan demasiado tiempo en un equipo. No se ejecuta en la familia, cosa buena. La solicitud fue simple, por favor, retire la respuesta de la marca.
    • +1 para el SingleBitPerPixelGridFit puntero para evitar este problema, gracias.
    • No entiendo lo que quieres decir con «Anti-aliasing no puede funcionar cuando sobre un fondo transparente.» ¿por Qué el problema sólo vienen con texto, y no en imágenes? por ejemplo, los iconos en el área de notificación puede tener perfecto anti-aliasing, y, sin embargo, usted no tiene idea de lo que su fondo es.

  4. 2

    Si usted está buscando algo que conserva suavizado un poco mejor de lo que GDI+ por defecto, usted puede llamar a Graphics.Clear con un chroma key, a continuación, quitar manualmente el chroma artefactos que resultan. (Ver ¿Por qué el Cordón se ven tan cutre? y Feos texto problema.)

    Esto es lo que, en última instancia terminó la solución de un problema similar:

    static Bitmap TextToBitmap(string text, Font font, Color foregroundColor)
    {
    SizeF textSize;
    using ( var g = Graphics.FromHwndInternal(IntPtr.Zero) )
    textSize = g.MeasureString(text, font);
    var image = new Bitmap((int)Math.Ceiling(textSize.Width), (int)Math.Ceiling(textSize.Height));
    var brush = new SolidBrush(foregroundColor);
    using ( var g = Graphics.FromImage(image) )
    {
    g.Clear(Color.Magenta);
    g.SmoothingMode = SmoothingMode.AntiAlias;
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    g.DrawString(text, font, brush, 0, 0);
    g.Flush();
    }
    image.MakeTransparent(Color.Magenta);
    //The image now has a transparent background, but around each letter are antialiasing artifacts still keyed to magenta.  We need to remove those.
    RemoveChroma(image, foregroundColor, Color.Magenta);
    return image;
    }
    static unsafe void RemoveChroma(Bitmap image, Color foregroundColor, Color chroma)
    {
    if (image == null) throw new ArgumentNullException("image");
    BitmapData data = null;
    try
    {
    data = image.LockBits(new Rectangle(Point.Empty, image.Size), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    for ( int y = data.Height - 1; y >= 0; --y )
    {
    int* row = (int*)(data.Scan0 + (y * data.Stride));
    for ( int x = data.Width - 1; x >= 0; --x )
    {
    if ( row[x] == 0 ) continue;
    Color pixel = Color.FromArgb(row[x]);
    if ( (pixel != foregroundColor) &&
    ((pixel.B >= foregroundColor.B) && (pixel.B <= chroma.B)) &&
    ((pixel.G >= foregroundColor.G) && (pixel.G <= chroma.G)) &&
    ((pixel.R >= foregroundColor.R) && (pixel.R <= chroma.R)) )
    {
    row[x] = Color.FromArgb(
    255 - ((int)
    ((Math.Abs(pixel.B - foregroundColor.B) +
    Math.Abs(pixel.G - foregroundColor.G) +
    Math.Abs(pixel.R - foregroundColor.R)) / 3)),
    foregroundColor).ToArgb();
    }
    }
    }
    }
    finally
    {
    if (data != null) image.UnlockBits(data);
    }
    }

    Es una vergüenza o GDI GDI+ no hacerlo ya, pero que sería sensato, ¿no? 🙂

    Si usted no es capaz de utilizar una unsafe contexto, usted puede fácilmente usar la misma lógica con Bitmap.GetPixel y Bitmap.SetPixel, aunque es mucho más lento.

    • Muy buena explicación.

Dejar respuesta

Please enter your comment!
Please enter your name here