ripper234
ripper234

Reputation: 230048

Why does Java ImageIO generate different images on different machines (linux vs Windows)?

I'm using javax.imageio to generate images from text strings on Windows and Linux, and I find the images are very different in quality (Linux = poor quality, small physical size, although same dimentions).

Linux (Ubunutu), 443 bytes

enter image description here

Windows 7, 1,242 bytes

enter image description here

I'm using the same font file (From Windows, uploaded to linux), and using this code to generate the images. Any idea how to improve the quality of the linux-generated images? Why are the generated images different in the first place?

I've tried setting explicit compression (via iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);), but I'm getting an UnsupportedOperationException when I try that.

Update:

Here is an SSCCE. I've updated my example and removed the font, the results are consistent. They also happen if you do set the font on both systems.

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Example {
    /**
     * <p>Create an image from text. <p/>
     * <p/>
     * http://stackoverflow.com/a/4437998/11236
     */
    public static void createFromText(String text, Path outputFile, int width, int height, Color color, int fontSize) {
        JLabel label = new JLabel(text, SwingConstants.CENTER);
        label.setSize(width, height);
        label.setForeground(color);

        BufferedImage image = new BufferedImage(
                label.getWidth(), label.getHeight(),
                BufferedImage.TYPE_INT_ARGB);

        Graphics g = null;
        try {
            // paint the html to an image
            g = image.getGraphics();
            g.setColor(Color.BLACK);
            label.paint(g);
        } finally {
            if (g != null) {
                g.dispose();
            }
        }

        // get the byte array of the image (as jpeg)
        try {
            ImageIO.write(image, "png", outputFile.toFile());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        Path output = Paths.get("/tmp/foo.png");
        createFromText("Custom Text", output, 200, 40, Color.blue, 30);
    }
}

Upvotes: 1

Views: 1725

Answers (2)

Jan
Jan

Reputation: 2478

Just a guess, but your images look like this could also come from different antialiasing behaviour when rendering the text to an image. Meaning that the difference is not caused during the compression or png encoding of the image, but already when rendering the text into the Image. If there is no text antialiasing, the image can be compressed to a smaller size because it contains less different colours, so that could also explain the difference in file size.

Try to experiment with explicitely specifiying antialising settings instead of relying on the system defaults, and see if that makes a difference. You can do this by adding RenderingHints to the Graphics2D object, e.g. the rendering hint text_antialising:

http://docs.oracle.com/javase/6/docs/api/java/awt/RenderingHints.html#KEY_TEXT_ANTIALIASING

Also see here for a discussion on font rendering behaviour:

Java Font Rendering

Upvotes: 3

Thomas
Thomas

Reputation: 661

one time you say that you only want to make string images, then in the code you say you make images from html... please specify this

for only strings: Maybe on linux the label itself sets other properties for the graphics, so do it yourself and don't use the labels paint method... could be linked with linux's Window-UI

html: try to use the JTextPane, it should have advanced html settings... maybe this improves the quality

Upvotes: 0

Related Questions