简体   繁体   中英

java image convolution

I am trying to apply smoothing filter to image. But I get this bug:

java.awt.image.ImagingOpException: Unable to convolve src image
at java.awt.image.ConvolveOp.filter(ConvolveOp.java:180)
at ocr.Resolution.smoothing(Resolution.java:102)
at ocr.Interface$ButtonListener.actionPerformed(Interface.java:332)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3260)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)

I have researched but couldn't find any exact solution. To see the source of problem, I have load images as icon. They are ok. Can the reason of this problem be that the image is loading later, so it couldn't apply the filter?

Also, I will apply thinning algorithm and some other filters too. Do you think If it is better to do in Processing instead of Java. Thank you for any help.

        filter = new float[] { 1.0f/121.0f,  2.0f/121.0f,   3.0f/121.0f,   2.0f/121.0f,   1.0f/121.0f,
                            2.0f/121.0f,  7.0f/121.0f,  11.0f/121.0f,   7.0f/121.0f,   2.0f/121.0f,
                            3.0f/121.0f, 11.0f/121.0f,  17.0f/121.0f,  11.0f/121.0f,   3.0f/121.0f,
                            2.0f/121.0f,  7.0f/121.0f,  11.0f/121.0f,   7.0f/121.0f,   2.0f/121.0f,
                            1.0f/121.0f,  2.0f/121.0f,   3.0f/121.0f,   2.0f/121.0f,   1.0f/121.0f};
    kernelWidth = 5;
    kernelHeight = 5;
    BufferedImageOp bufOp ;
    BufferedImage bufImg;
    Image img;

    img = Toolkit.getDefaultToolkit().getImage(Interface.picPath); //load image        
    ImageSize size = new ImageSize(img);// instance to get image dimensions
    bufImg = new BufferedImage (size.getwidth(),size.getheight(),BufferedImage.TYPE_INT_RGB); 
    try {
    bufImg = ImageIO.read(new File(Interface.picPath) );

    } catch (IOException ex) {
    Logger.getLogger(Resolution.class.getName()).log(Level.SEVERE, null, ex);
    }

    kernel = new Kernel( kernelWidth, kernelHeight, filter);
    bufOp = new ConvolveOp(kernel); 
    bufImg = bufOp.filter(bufImg, null);

I have found a solution. Instead of creating BufferedImage(bufImg) using URl, I converted the image itself (img ) to BufferedImage and it runs now.

public void smoothing(){
     filter = new float[] { 1.0f/121.0f,  2.0f/121.0f,   3.0f/121.0f,   2.0f/121.0f,   1.0f/121.0f,
                            2.0f/121.0f,  7.0f/121.0f,  11.0f/121.0f,   7.0f/121.0f,   2.0f/121.0f,
                            3.0f/121.0f, 11.0f/121.0f,  17.0f/121.0f,  11.0f/121.0f,   3.0f/121.0f,
                            2.0f/121.0f,  7.0f/121.0f,  11.0f/121.0f,   7.0f/121.0f,   2.0f/121.0f,
                            1.0f/121.0f,  2.0f/121.0f,   3.0f/121.0f,   2.0f/121.0f,   1.0f/121.0f};
    kernelWidth = 5;
    kernelHeight = 5;
    kernel = new Kernel( kernelWidth, kernelHeight, filter);
    op = new ConvolveOp(kernel); 

    img = Toolkit.getDefaultToolkit().getImage(Interface.picPath);
    imageToBufferedImage(img);
    bufImg = op.filter(bufImg, null);

    icon = new ImageIcon(img.getScaledInstance(175, 175, Image.SCALE_DEFAULT));
    icon2 = new ImageIcon(img.getScaledInstance(300, 300, Image.SCALE_DEFAULT));
    Interface.label3.setIcon(icon);
    Interface.label8.setIcon(icon2);

}

public  void imageToBufferedImage(Image im) {
    ImageSize size = new ImageSize(im);
    bufImg = new BufferedImage (size.getwidth(), size.getheight(),BufferedImage.TYPE_INT_RGB);
    Graphics graph = bufImg.getGraphics();
    graph.drawImage(im, 0, 0, null);
    graph.dispose();

}

I just had the "same" error and dug really deep into the source code to find out what was wrong. I ended up reading https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/native/sun/awt/medialib/awt_ImagingLib.c

As you can see, method Java_sun_awt_image_ImagingLib_convolveRaster has a dozen ways to return 0 or -1 (actually there are 13 ways).

Whenever that method returns something non-positive, this case ends up as the exception Ecrin posted, and there's no specific information what went wrong because the method provides none in the first place.

The best you can do is start with a working example, like that one Ecrin provided, hopefully it's working also for you. Then change it step by step.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM