Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I can correctly use AffineTransformOp.filter on a png/jpeg image. But when I subclass the AffineTransformOp it throws an exception! The following minimal example shows this:

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.imageio.*;
import java.io.*;
public class Strange  extends JPanel {
  public static void main(String args[]) throws Exception {
      BufferedImage from = (BufferedImage) ImageIO.read(new File(args[0]));
      MyTrans at = new MyTrans();
      AffineTransformOp at2 = new AffineTransformOp(new AffineTransform(), AffineTransformOp.TYPE_BILINEAR);
      System.err.println("Bad = "+at.getTransform());
      System.err.println("Good = "+at2.getTransform());
      BufferedImage bi1 = at.filter(from,null);//1
      BufferedImage bi2 = at2.filter(from,null);//2
class MyTrans extends AffineTransformOp {
    public MyTrans() {
        super(new AffineTransform(), TYPE_BILINEAR);

The line marked with 1 throws an ImagingOpException:Unable to transform src image. But I comment out that line, then the next line (which does exactly the same thing) runs smoothly. The transform here is just the identity transform. I am using java 8 on Ubuntu 16.04. Any png or jpeg image causes thiso SO I am not attaching the image.

good catch - now lets move on to some useful work - you may dive in to the source to see what happens with that super stuff – gpasch Sep 22, 2018 at 8:25

AffineTransformOp.filter(src, dst) internally calls ImagingLib.filter(this, src, dst) from package sun.awt.image.ImagingLib , on line 284.

if (ImagingLib.filter(this, src, dst) == null) { throw new ImagingOpException ("Unable to transform src image");

The behavior we are observing is related on how ImagingLib.filter() is implemented. This method checks if the first parameter corresponds to any of these classes:

  • LookupOp
  • AffineTransformOp
  • ConvolveOp
  • When ImagingLib.filter is called the first parameter passed to the function is this. In the sample code you wrote: at.class is equal to "MyTrans" and at2.class is equal to "AffineTransformOp".

    Take a look at the code below, it belongs to ImagingLib.filter() source code.

     public static BufferedImage filter(BufferedImageOp var0, BufferedImage var1, BufferedImage var2) {
            BufferedImage var3 = null;
            switch(getNativeOpIndex(var0.getClass())) {
            case 0:
                LookupTable var4 = ((LookupOp)var0).getTable();
                if (var4.getOffset() != 0) {
                    return null;
                if (var4 instanceof ByteLookupTable) {
                    ByteLookupTable var9 = (ByteLookupTable)var4;
                    if (lookupByteBI(var1, var2, var9.getTable()) > 0) {
                        var3 = var2;
                break;
            case 1:
                AffineTransformOp var5 = (AffineTransformOp)var0;
                double[] var6 = new double[6];
                AffineTransform var7 = var5.getTransform();
                var5.getTransform().getMatrix(var6);
                if (transformBI(var1, var2, var6, var5.getInterpolationType()) > 0) {
                    var3 = var2;
                break;
            case 2:
                ConvolveOp var8 = (ConvolveOp)var0;
                if (convolveBI(var1, var2, var8.getKernel(), var8.getEdgeCondition()) > 0) {
                    var3 = var2;
            if (var3 != null) {
                SunWritableRaster.markDirty(var3);
            return var3;
    

    So, when getNativeOpIndex(var0.getClass()) is invoked, because "MyTrans" is not the class type expected, it returns -1 therefore it does not mach any case on the switch and null is returned.

    Thank you so much for the detailed answer. However, this behavior should be considered a bug, since it violates the basic subclassing contract: A subclass object is also a superclass object. I think ImagingLib.filter should actually check that the current class is a subclass of AffineTransformOp. – Arnab Chakraborty Sep 23, 2018 at 14:29

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.