我有一个程序,将改变阈值在img,但我不知道如何刷新图像。它将创建两个JFrame窗口,一个用于滑动条,一个用于图像。我确实从滑块中获取value去到threshold。但是我如何刷新改变的图像。对不起,张贴整个代码,但我不能弄清楚这个
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.lang.Math;
import java.util.ArrayList;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.CvType;
import org.opencv.core.MatOfDouble;
public class Draw extends JFrame{
JSlider slider;
JLabel label;
JLabel test1;
int Actual;
int value = 100;
public Draw(){
setLayout(new FlowLayout());
slider = new JSlider(JSlider.HORIZONTAL, 0, 255, 100);
add(slider);
label = new JLabel();
add(label);
test1 = new JLabel();
add(test1);
event e = new event();
slider.addChangeListener(e);
}
public class event implements ChangeListener {
public void stateChanged(ChangeEvent e){
value = slider.getValue();
label.setText("Current Value " + value);
}
}
public static void main(String agrs[]){
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Draw sl = new Draw();
sl.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sl.setSize(300,100);
sl.setVisible(true);
sl.setTitle("Slider Bar");
sl.converter();
sl.repaint();
sl.revalidate();
}
public void converter(){
Mat imageInMat = Imgcodecs.imread("C:/Users/ja/workspace/imgtomath/bin/imgtomath/bowl.jpg",0);
if(imageInMat.empty()== true)
{System.out.println("Error no image found!!");}
else
System.out.println("Image loaded");
Mat thresh = new Mat();
Imgproc.threshold(imageInMat, thresh, value, 250, Imgproc.THRESH_BINARY_INV);
BufferedImage bufImage = Mat2BufferedImage(thresh);
displayImage(bufImage);
}
public BufferedImage Mat2BufferedImage(Mat m){
//source: http://answers.opencv.org/question/10344/opencv-java-load-image-to-gui/
//Fastest code
//The output can be assigned either to a BufferedImage or to an Image
int type = BufferedImage.TYPE_BYTE_GRAY;
if ( m.channels() > 1 ) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = m.channels()*m.cols()*m.rows();
byte [] b = new byte[bufferSize];
m.get(0,0,b); // get all the pixels
BufferedImage image = new BufferedImage(m.cols(),m.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(b, 0, targetPixels, 0, b.length);
return image;
}
public void displayImage(Image img2)
{
//BufferedImage img=ImageIO.read(new File("/HelloOpenCV/lena.png"));
ImageIcon icon=new ImageIcon(img2);
JFrame frame=new JFrame();
frame.setLayout(new FlowLayout());
frame.setSize(img2.getWidth(null)+50, img2.getHeight(null)+50);
JLabel lbl=new JLabel();
lbl.setIcon(icon);
frame.add(lbl);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
我理解的问题是,如果你从stateChanged()
调用converter()
,它会创建一个新的JFrame每次你改变滑块上的值?
这里有一个简单的建议来防止这种情况:
stateChanged
:
public void stateChanged(ChangeEvent e){
value = slider.getValue();
label.setText("Current Value " + value);
converter();
}
displayImage
:
private JFrame frame = new JFrame("Image JFrame");
JLabel lbl = null;
public void displayImage(Image img2){
if(lbl==null){
lbl = new JLabel();
frame.setLayout(new FlowLayout());
frame.setSize(img2.getWidth(null)+50, img2.getHeight(null)+50);
frame.add(lbl);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
ImageIcon icon=new ImageIcon(img2);
lbl.setIcon(icon);
}
还有:您应该从您的主方法在Event线程上创建Swing组件,如https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html