Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is image printed from Java fuzzy?

Tags:

java

swing

I have an application which heavily leverages swing components, using JButtons and JLabels within a JPanel. I use a GridBagLayout to layout these components, and on screen they display just fine. Running on windows if that matters.

The problem I have been struggling with has to do with the clarity of the printed image, whether this is printed to paper, or a jpg. The image tends to look muddy. The edges of buttons, the text within buttons or labels, even straight lines look fuzzy.

Below is an example that generates a 50x50 jpg which contains a 40x40 rectangle inside of it. There seems to be a faint shadow line inside and outside of the rectangle, faint dots at the corners, and even the edges of the line seem fuzzy. I see the same results with swing components too.

In my searching and reading, I've found a lot of references to RenderingHints, but I've seen too many suggestions of the form "try setting this" without any explanation to discern which hint(s) might apply.

Any suggestions/pointers would be appreciated.

import java.lang.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.io.*;

public class MyFrame extends JFrame {

  public static void main(String[] args) {

     new MyFrame(); 

  }

  MyFrame() {
      JButton button;

      button = new JButton("print jpg");

      button.addActionListener( new ActionListener() {
         public void actionPerformed(ActionEvent evt) {
               takePicture();
         }
      });

      setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

      add(button);

      pack();
      setVisible(true);

  }

  void takePicture() {

    BufferedImage img = new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
    Graphics g = img.getGraphics();

    g.setColor(Color.white);
    g.fillRect(0,0,50,50);

    g.setColor(Color.black);
    g.drawRect(5,5,40,40);

    try {
      ImageIO.write(img, "jpg", new File("output_file.jpg") );
    }
    catch (IOException e) {
      e.printStackTrace();
    }

  }
}
like image 682
L Jones Avatar asked Feb 02 '26 18:02

L Jones


1 Answers

What you see is probably JPEG compression artifacts. If you will use some lossless format (like PNG), you'll get the desired image.

Here's the version that outputs perfectly crisp rectangle:

import java.awt.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.io.*;

public class PrintImage {
    public static void main(String[] args) throws Exception {
        BufferedImage img = new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D) img.getGraphics();

        g.setColor(Color.white);
        g.fillRect(0,0,50,50);

        g.setColor(Color.black);
        g.drawRect(5,5,40,40);

        ImageIO.write(img, "png", new File("output_file.png") );
    }
}

Note that I used png as output format - it doesn't lose information to save space, unlike jpg.

Also make sure that your image viewer doesn't try to interpolate pixels when you zoom in - or else you'll see blurry lines. Image editing software usually doesn't do that, so you can use Paint to check that you indeed have the desired image.

like image 102
Rogach Avatar answered Feb 04 '26 10:02

Rogach



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!