Why is the image printed from Java fuzzy?

I have an application that makes heavy use of swing components using JButtons and JLabels inside a JPanel. I am using a GridBagLayout to lay out these components and they display just fine on screen. Run on windows, if it matters.

The problem I was struggling with related to the clarity of the printed image, whether printing on paper or jpg. The image tends to look dirty. The edges of buttons, text inside buttons or labels, even straight lines appear fuzzy.

Below is an example that generates a 50x50 jpg that has a 40x40 rectangle inside it. There seems to be a small shadow line on the inside and outside of the rectangle, faint points in the corners, and even the edges of the line appear fuzzy. I also see the same results with swing components.

In my searches and reading I found many references to RenderingHints, but I have seen too many suggestions for a try-install-it form without any explanation to determine what hints 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();
    }

  }
}

      

+3


source to share


1 answer


What you are seeing is probably JPEG compression artifacts. If you use some kind of lossless format (like PNG), you will get the image you want.

Here's a version that outputs a 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 the output format - it does not lose information to save space, unlike jpg.

Also make sure your image viewer is not trying to interpolate pixels when zooming in - otherwise you will see blurry lines. Image editing software doesn't usually do this, so you can use Paint to make sure you actually have the image you want.

+3


source







All Articles