2010-11-26 18 views
6

Soy nuevo en Java y trato de usar gráficos Java2D para crear una imagen. Pero el resultado viene como anti-aliased. Intenté muchas formas de rectificarlo, pero no funciona. Los personajes están distorsionados o dentados.Gráficos de Java2D antialias

public BufferedImage createNameOnButton(String label) { 
    int messageWidth = 0; 
    Font font = new Font("Arial", Font.PLAIN, 11); 

    BufferedImage bi = new BufferedImage(
     10, 10, BufferedImage.TYPE_INT_RGB); 

    Graphics2D g2d = (Graphics2D) bi.getGraphics(); 
    g2d.setRenderingHint(
     RenderingHints.KEY_ANTIALIASING, 
     RenderingHints.VALUE_ANTIALIAS_ON); 
    g2d.setRenderingHint(
     RenderingHints.KEY_TEXT_ANTIALIASING, 
     RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
    g2d.setRenderingHint(
     RenderingHints.KEY_FRACTIONALMETRICS, 
     RenderingHints.VALUE_FRACTIONALMETRICS_ON); 
    g2d.setFont(font); 

    bi = g2d.getDeviceConfiguration() 
     .createCompatibleImage(500, 30, Transparency.BITMASK); 
    FontMetrics fm = bi.getGraphics().getFontMetrics(font); 
    int messageHeight = fm.getHeight() - fm.getDescent(); 
    for (char ch : label.toCharArray()) { 
     messageWidth += fm.charWidth(ch); 
    } 

    bi = bi.getSubimage(50, 0, messageWidth + 10, fm.getHeight()); 
    Graphics g = bi.getGraphics(); 
    g.setColor(Color.black); 
    AttributedString as = new AttributedString(label); 
    as.addAttribute(TextAttribute.FONT, font); 
    g.drawString(as.getIterator(), 5, messageHeight); 
    g2d.dispose(); 
    g.dispose(); 
    return bi; 
} 

¿Alguien me puede ayudar a solucionar el error?

+0

¿Qué está creando primero una imagen 10x10? Su código es realmente intrincado por lo que se supone que debe hacer. –

+3

No estoy completamente seguro de entender. Por su pregunta, entiendo que no quiere que los personajes sean antialias. Pero al leer el código, no es de extrañar, ya que dice ANTIALIAS_ON en todas partes. ¿Podrías explicar? –

+0

Gracias por afirmar que - Probé el código con ANTIALIAS_OFF pero hay algunos caracteres que aún aparecen como anti-alias (no todos los caracteres) como, la '\' vertical de N, 'a', 'v', 'e' , y ',' o '- básicamente los bordes de los caracteres no son suaves. ¿Hay algo más que tenga que hacer? – Prakash

Respuesta

4

Como Traroth indican que es más probable debido a

g2d.setRenderingHint(
    RenderingHints.KEY_ANTIALIASING, 
    RenderingHints.VALUE_ANTIALIAS_ON); 
g2d.setRenderingHint(
    RenderingHints.KEY_TEXT_ANTIALIASING, 
    RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 

En cambio, esta debe ser

g2d.setRenderingHint(
    RenderingHints.KEY_ANTIALIASING, 
    RenderingHints.VALUE_ANTIALIAS_OFF); 
g2d.setRenderingHint(
    RenderingHints.KEY_TEXT_ANTIALIASING, 
    RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); 
+1

Gracias por decir que probé el código con ANTIALIAS_OFF, pero hay algunos caracteres que aún aparecen como anti-alias (no todos los caracteres) como, la '\' vertical de N, 'a', 'v', 'e' 'y', 'o' - básicamente los bordes de los caracteres no son suaves. ¿Hay algo más que tenga que hacer? – Prakash

+8

Parece que no entiende qué significa anti-aliasing. Anti-aliased = suave. – lbalazscs

11

Suponiendo que realmente desea el texto liso (no-aliasing), TextLayout puede hacer esto más fácil. El constructor FontRenderContext puede administrar la configuración de anti-aliasing y de medidas fraccionarias.

Adición: El uso de g2d.setColor(Color.blue) parece producir el efecto esperado.

Adición: En Mac OS X, la aplicación Pixie en /Developer/Applications/Graphics Tools/ es conveniente para examinar los píxeles anti-alias. En otras plataformas, se puede usar Zoom.

alt text

/** @see https://stackoverflow.com/questions/4285464 */ 
public class BITest extends JPanel { 

    private BufferedImage image = createNameOnButton("Sample"); 

    public BITest() { 
     this.setPreferredSize(new Dimension(
      image.getWidth(), image.getHeight())); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawImage(image, 0, 0, null); 
    } 

    public BufferedImage createNameOnButton(String label) { 
     Font font = new Font("Arial", Font.PLAIN, 64); 
     FontRenderContext frc = new FontRenderContext(null, true, true); 
     TextLayout layout = new TextLayout(label, font, frc); 
     Rectangle r = layout.getPixelBounds(null, 0, 0); 
     System.out.println(r); 
     BufferedImage bi = new BufferedImage(
      r.width + 1, r.height + 1, 
      BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2d = (Graphics2D) bi.getGraphics(); 
     g2d.setColor(Color.blue); 
     layout.draw(g2d, 0, -r.y); 
     g2d.dispose(); 
     return bi; 
    } 

    private void display() { 
     JFrame f = new JFrame("BITest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setUndecorated(true); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new BITest().display(); 
      } 
     }); 
    } 
} 
+0

Gracias por el programa de ejemplo. Mi requisito es escribir una función que devuelva una Imagen Buffered que contenga un texto del patrón "Entregarme a ". La frase "Deliver Me to" debe estar en color negro, mientras que "" que se recoge dentro del flujo debe ser de color azul. ¿Puede por favor proporcionar algunas entradas sobre el mismo? – Prakash

+0

También se olvidó de agregar que, dado que debe colocarse en un botón, el tamaño de la imagen debe ser de ancho y alto específicos. Probé el programa de muestra, pero la imagen procesada es completamente negra y no pude ver el texto escrito. Tenga en cuenta que soy completamente nuevo en Java. – Prakash

+0

Solo para agregar: obtuve la imagen, pero en realidad necesito almacenarla y verla igual que dentro de un archivo. Entonces, ¿cómo puedo escribir lo que se muestra mediante el método display() en un archivo? – Prakash

2

me encontré con que simplemente this line hace el truco:

g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 

Después de eso, sólo tiene que utilizar drawString().

Cuestiones relacionadas