Texto de Java en la imagen

Estoy cargando una imagen en una imagen en buffer y luego escribiendo un texto sobre ella. Después de agregar texto, la imagen se vuelve borrosa y el texto distorsionado. Tengo TEXTO ANTIALIASING ENCENDIDO. Se puede ver como adjunto.

enter image description here

Debería poder controlar la calidad del texto con las sugerencias de representación que se muestran en las otras respuestas. Sé que funciona porque lo he hecho mucho, así que creo que debe ser algo más que cause la degradación de la calidad en este caso.

  1. ¿Cómo se verifica la calidad de la imagen? ¿Pinta el BufferedImage generado directamente en una pantalla gráfica en su aplicación Java o lo guarda en el disco, es decir, como JPEG? Si lo guarda en el disco intente guardarlo como PNG 24 y no como JPEG. Supongo que su pantalla de escritorio se está ejecutando en color verdadero (profundidad de color de 32 o 24 bits), ¿verdad?
  2. ¿Estás seguro de que la imagen se creó realmente como BufferedImage.TYPE_INT_RGB? Si no tiene control sobre la creación de la Imagen Buffered en su código, intente crear una nueva Imagen Buffered con TYPE_INT_RGB y coloque la fuente en esta y luego dibuje el texto en ella.
  3. Intente configurar RenderingHints.KEY_DITHERING en RenderingHints.VALUE_DITHER_DISABLE (aunque esto no debería ser necesario para imágenes en color verdadero).

Si esto aún no ayuda a encontrar la causa, proporcione más información (versión VM, sistema operativo) y código fuente. La renderización de texto se ha vuelto bastante buena con JDK 1.6 Update 10, pero también versiones anteriores podían producir texto limpio en imágenes, simplemente no se veía tan bien debido a un antialiasing menos sofisticado.

en respuesta a tu comentario:

Los bordes filosos de alto contraste como en el texto son un problema general con la compresión JPEG ya que no es una compresión sin pérdida. Si realmente necesita ir con JPEG y no puede cambiar a PNG, puede ajustar la calidad de compresión de su imagen guardada para encontrar un mejor compromiso entre la calidad de la imagen y el tamaño del archivo. Consulte el siguiente código sobre cómo establecer la calidad de compresión cuando guarda un JPEG.

import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import javax.imageio.stream.ImageOutputStream; //---- float quality = 0.85f; File outfile = new File( "MyImage.jpg" ); BufferedImage image = ...; ImageWriter imgWriter = ImageIO.getImageWritersByFormatName( "jpg" ).next(); ImageOutputStream ioStream = ImageIO.createImageOutputStream( outfile ); imgWriter.setOutput( ioStream ); JPEGImageWriteParam jpegParams = new JPEGImageWriteParam( Locale.getDefault() ); jpegParams.setCompressionMode( ImageWriteParam.MODE_EXPLICIT ); jpegParams.setCompressionQuality( quality ); imgWriter.write( null, new IIOImage( image, null, null ), jpegParams ); ioStream.flush(); ioStream.close(); imgWriter.dispose(); 
 import java.awt.image.BufferedImage; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.imageio.*; import java.io.*; import javax.imageio.stream.ImageOutputStream; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import java.util.Locale; class ImageCompressionDemo { private BufferedImage originalImage; private BufferedImage textImage; private JPanel gui; private JCheckBox antialiasing; private JCheckBox rendering; private JCheckBox fractionalMetrics; private JCheckBox strokeControl; private JCheckBox colorRendering; private JCheckBox dithering; private JComboBox textAntialiasing; private JComboBox textLcdContrast; private JLabel jpegLabel; private JLabel pngLabel; private JTextArea output; private JSlider quality; private int pngSize; private int jpgSize; final static Object[] VALUES_TEXT_ANTIALIASING = { RenderingHints.VALUE_TEXT_ANTIALIAS_OFF, RenderingHints.VALUE_TEXT_ANTIALIAS_ON, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB }; final static Object[] VALUES_TEXT_LCD_CONTRAST = { new Integer(100), new Integer(150), new Integer(200), new Integer(250) }; ImageCompressionDemo() { int width = 280; int height = 100; gui = new JPanel(new BorderLayout(3,4)); quality = new JSlider(JSlider.VERTICAL, 0, 100, 75); quality.setSnapToTicks(true); quality.setPaintTicks(true); quality.setPaintLabels(true); quality.setMajorTickSpacing(10); quality.setMinorTickSpacing(5); quality.addChangeListener( new ChangeListener(){ public void stateChanged(ChangeEvent ce) { updateImages(); } } ); gui.add(quality, BorderLayout.WEST); originalImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); textImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); JPanel controls = new JPanel(new GridLayout(0,1,0,0)); antialiasing = new JCheckBox("Anti-aliasing", false); rendering = new JCheckBox("Rendering - Quality", true); fractionalMetrics = new JCheckBox("Fractional Metrics", true); strokeControl = new JCheckBox("Stroke Control - Pure", false); colorRendering = new JCheckBox("Color Rendering - Quality", true); dithering = new JCheckBox("Dithering", false); controls.add(antialiasing); controls.add(fractionalMetrics); textLcdContrast = new JComboBox(VALUES_TEXT_LCD_CONTRAST); JPanel lcdContrastPanel = new JPanel(new FlowLayout(FlowLayout.LEADING)); lcdContrastPanel.add(textLcdContrast); lcdContrastPanel.add(new JLabel("Text LCD Contrast")); controls.add(lcdContrastPanel); textAntialiasing = new JComboBox(VALUES_TEXT_ANTIALIASING); controls.add(textAntialiasing); controls.add(dithering); controls.add(rendering); controls.add(colorRendering); controls.add(strokeControl); ItemListener itemListener = new ItemListener(){ public void itemStateChanged(ItemEvent e) { updateImages(); } }; antialiasing.addItemListener(itemListener); rendering.addItemListener(itemListener); fractionalMetrics.addItemListener(itemListener); strokeControl.addItemListener(itemListener); colorRendering.addItemListener(itemListener); dithering.addItemListener(itemListener); textAntialiasing.addItemListener(itemListener); textLcdContrast.addItemListener(itemListener); Graphics2D g2d = originalImage.createGraphics(); GradientPaint gp = new GradientPaint( 0f, 0f, Color.red, (float)width, (float)height, Color.orange); g2d.setPaint(gp); g2d.fillRect(0,0, width, height); g2d.setColor(Color.blue); for (int ii=0; ii 

Captura de pantalla

Salidas típicas

 Fractional Metrics: true Nonantialiased text mode PNG size: 7390 bytes JPG size: 7036 bytes quality: 35 Fractional Metrics: true Antialiased text mode PNG size: 8741 bytes JPG size: 8663 bytes quality: 55 Fractional Metrics: false Antialiased text mode PNG size: 8720 bytes JPG size: 8717 bytes quality: 55 

eso es solo java simplemente apague el texto anti aliasing. o si realmente lo necesita, renderice el texto en una imagen separada, si el texto es negro, obtenga todos los píxeles con color por debajo de rgb (100,100,100) y ajústelos a 0. luego coloque ese búfer en su imagen principal.

prueba esto:

 public static void setGraphicsQuality(Graphics2D g2D) { g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); }