JDK-4475238 : Bicubic Interpolation RenderingHints broken?
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2001-06-27
  • Updated: 2001-06-27
  • Resolved: 2001-06-27
Related Reports
Duplicate :  
Description

Name: bsC130419			Date: 06/27/2001


java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)


On my Win2k system, Graphics2D.drawImage() does not interpolate correctly with
bicubic interpolation set.  In fact, it works exactly as bilinear does.

The sample program shows 8 versions of the image.  Top 3 are nearest neighbor,
bilinear, and "bicubic".  The bottom 5 are getScaledInstance()s of the image.
I believe the SCALE_SMOOTH image should be more what bicubic looks like.

I tried this program out using the "sun.gif" from SwingSet2.jar in the demos.

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

public class TestInterpolation extends JPanel
{
    // the image to do scale tests on
    private Image image;
    // scaled versions
    private Image scaledInstance1;
    private Image scaledInstance2;
    private Image scaledInstance3;
    private Image scaledInstance4;
    private Image scaledInstance5;
    private boolean scaledVersionsMadeYet = false; // yuck :)
    
    // set the buffer (number of pixels between the images)
    int buffer = 5;
    // sets what percentage of original size the image will be
    double xScale = .34;
    double yScale = .34;
    
    public static void main(String[] argv)
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new TestInterpolation());
        f.setSize(495, 250);
        f.show();
    }

    public void paintComponent(Graphics g)
    {
        // get the image
        image = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("sun.gif"));
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        
        // calculate new dimensions from original ones
        int origWidth = image.getWidth(this);
        int origHeight = image.getHeight(this);
        int width = (int) (xScale * origWidth);
        int height = (int) (yScale * origHeight);

        // SUPER hack... so it didn't keep making scaled version (and consuming
        // memory) i just checked to see if it had made the scaled version yet.
        // also note it checks to make sure the width/height aren't zero still
        if (!scaledVersionsMadeYet && width != 0 && height != 0)
        {
            scaledVersionsMadeYet = true;
            scaledInstance1 = image.getScaledInstance(width, height, Image.SCALE_DEFAULT);
            scaledInstance2 = image.getScaledInstance(width, height, Image.SCALE_FAST);
            scaledInstance3 = image.getScaledInstance(width, height, Image.SCALE_REPLICATE);
            scaledInstance4 = image.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
            scaledInstance5 = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        }

        // draw 3 versions of the image, with nearest neighbor, bilinear,
        // and bicubic interpolation
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        g2.drawImage(image, buffer, buffer, width, height, this);
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2.drawImage(image, buffer * 2 + width, buffer, width, height, this);
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2.drawImage(image, buffer * 3 + width * 2, buffer, width, height, this);
        
        // now draw versions using getScaledInstance()
        if (scaledInstance1 != null)
            g2.drawImage(scaledInstance1, buffer, buffer * 2 + height, this);
        if (scaledInstance2 != null)
            g2.drawImage(scaledInstance2, buffer * 2 + width, buffer * 2 + height, this);
        if (scaledInstance3 != null)
            g2.drawImage(scaledInstance3, buffer * 3 + width * 2, buffer * 2 + height, this);
        if (scaledInstance4 != null)
            g2.drawImage(scaledInstance4, buffer * 4 + width * 3, buffer * 2 + height, this);
        if (scaledInstance5 != null)
            g2.drawImage(scaledInstance5, buffer * 5 + width * 4, buffer * 2 + height, this);
    }
}

(Review ID: 127423) 
======================================================================