Java AWT and Java 2D: Load, Resize and Export Images - Yenra

Resize a local image with Java 2D, preserve proportions, handle transparency and verify the exported file.

Three navy frames show the same mountain scene at decreasing sizes beside a clear pane with an amber corner.
Conceptual illustration: resizing changes dimensions while a deliberate export policy handles transparency.

Java 2D can turn a local image into a thumbnail without opening a window. A reliable conversion states its rules: fit within a box, preserve proportions, avoid enlargement and choose what happens to transparent pixels. The example here writes a new PNG or JPEG and checks the result.

Prepare a bounded local-image task

The download uses the standard java.desktop APIs and was checked with Java 25. Use a small image you own or trust, with an existing output directory and a new output filename. This teaching utility decodes the source into memory; a public upload service needs input-size, decoded-dimension and resource limits before it accepts arbitrary images.

Download the source, checks and README (ZIP)

javac ResizeImage.java ImageCheck.java
java -Djava.awt.headless=true ResizeImage input.png thumb.png 300 300 png

Replace input.png with your source. The next arguments are the output filename, maximum width, maximum height and format. Use a matching extension. The utility accepts bounds from 1 to 4,096 pixels and refuses to overwrite an existing output. Choose a fresh filename for each experiment.

Work out the output dimensions

For source width W and height H, calculate scale = min(1, maxWidth/W, maxHeight/H) using floating-point division. Multiply each source dimension by that scale, round to the nearest integer and keep at least one pixel. The shared scale preserves proportions, subject to whole-pixel rounding.

On narrow screens, scroll this table horizontally. Keyboard users can focus it and use the arrow keys.

Worked resize cases
SourceBounding boxOutputInterpretation
1,200 × 800300 × 300300 × 200Width limits the scale to one quarter.
800 × 1,200300 × 300200 × 300Height limits the scale.
120 × 80300 × 300120 × 80The example preserves small images without enlarging.

A square bounding box produces a rectangular image when the source is rectangular. To create a square tile, decide separately whether to crop or add padding; those choices change the visible content. The sample deliberately implements only fitting.

Choose pixel storage and draw once

BufferedImage holds decoded pixels. PNG output uses an ARGB image, which can retain alpha transparency. JPEG output uses RGB: the code first fills the destination white, then draws the source over it. That produces a deliberate background instead of relying on an encoder to interpret transparent pixels.

Graphics2D g = out.createGraphics();
try {
    if (jpeg) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, w, h);
    }
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                       RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    g.drawImage(in, 0, 0, w, h, null);
} finally {
    g.dispose();
}

The Graphics2D API describes rendering state and image transforms. Bicubic interpolation is a useful starting point; inspect small text, sharp edges and photographs at the final display size. A severe reduction can justify a more careful resampling pipeline. The sample makes no print-color or archival-fidelity claim.

Check the reader and writer

ImageIO.read can return null when no installed reader recognizes the input, while ImageIO.write reports whether a writer was found. The code checks both outcomes. The ImageIO reference documents those behaviors. A filename extension alone cannot establish that the file is a supported image.

Creating a new destination image and using the convenience writer does not preserve all source metadata. Check camera orientation, color appearance, transparency and any metadata requirements explicitly. This JPEG path uses the writer default quality; selecting compression quality requires an ImageWriter and its write parameters.

Run java -Djava.awt.headless=true ImageCheck. It verifies the 300 × 200 result, preserved PNG transparency, white JPEG compositing, the no-enlargement rule and an actual export/read-back. It prints a temporary directory containing generated test images. Open your own output separately, inspect its pixel dimensions, and compare it at 100% zoom before using it.

Continue with a related task