生物屋さんのためのゼロからのプログラミング

―忘れないための覚書 (たま~に更新)―

JSliderを使って、画像の輝度を変える。

ここでは、JSliderを使って画像の輝度値を変えてみた。
まずは、ソースを記す。

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputAdapter;

public class SlideInt extends JFrame implements ChangeListener {

	JFrame showFrame;
	JFrame changeFrame;
	JSlider slide;
	JLabel labe;
	JLabel value;
	BufferedImage img;
	BufferedImage img1;
	MyPanel mypane;
	MyPanel1 mypane1;
	int h;
	int w;
	int x0;
	int y0;

	//画像を開く
	public void OpenImage () {
		try {
			img = ImageIO.read(new File("C:\\Users\\aki-miya\\Desktop\\GFP-KDEL.png"));
			img1 = ImageIO.read(new File("C:\\Users\\aki-miya\\Desktop\\GFP-KDEL.png"));
			h = img.getHeight(); //画像の高さを取得
			w = img.getWidth(); //画像の幅を取得

			showFrame = new JFrame("Raw Image");
			changeFrame = new JFrame ("Change Intensity");
			showFrame.setSize (w, h);
			changeFrame.setSize (w, h);
			showFrame.setBounds (300, 100, w, h);
			changeFrame.setBounds (600, 100, w, h);
			showFrame.setVisible(true);
			changeFrame.setVisible(true);
			mypane = new MyPanel (w, h);
			mypane1 = new MyPanel1(w, h);
			mypane1.addMouseListener(new MouseCheck());
			mypane1.addMouseMotionListener(new MouseCheck());
			showFrame.getContentPane().add(mypane, BorderLayout.CENTER);
			changeFrame.getContentPane().add(mypane1, BorderLayout.CENTER);

		} catch (IOException ex) {
			System.out.println("Miss");
		}
	}

	//確認用にマウスを置いたポイントの輝度値を取得し、表示
	class MouseCheck extends MouseInputAdapter {
		public void mouseMoved (MouseEvent me) {
			x0 = me.getX();
			y0 = me.getY();
			value.setText(String.valueOf(img1.getRaster().getDataBuffer().getElem(y0*w + x0)));
		}
	}

	//画像を描画するツール
	public class MyPanel extends JPanel {
		public MyPanel (int w, int h) {
			setSize(w,h);
		}

		public void paintComponent (Graphics g) {
			g.drawImage(img, 0, 0, w, h, this);
		}
	}

	//画像を描画するツール
	public class MyPanel1 extends JPanel {
		public MyPanel1 (int w, int h) {
			setSize(w,h);
		}

		public void paintComponent (Graphics g) {
			g.drawImage(img1, 0, 0, w, h, this);
		}
	}


//スライダーのノブを動かした時のイベント
	public void stateChanged (ChangeEvent e) {

		labe.setText("Val = " + slide.getValue());

		//輝度値を変える
		for (int i = 0; i < w*h; i++) {
			if (img.getRaster().getDataBuffer().getElem(i) < slide.getValue()) {
				img1.getRaster().getDataBuffer().setElem(i, slide.getValue());
			} else {
				img1.getRaster().getDataBuffer().setElem(i, img.getRaster().getDataBuffer().getElem(i));
			}
		}
	mypane1.repaint();
	}

	SlideInt () {
		slide = new JSlider (0, 64000); //開いた画像が16bitなので、この値に設定
		labe = new JLabel ("val slide = 0");
		value = new JLabel ("val = null");
		slide.addChangeListener (this);  //Slideを可変にする
		JPanel pane = new JPanel ();
		pane.setLayout(null);
		slide.setBounds(10, 10, 100, 30);
		labe.setBounds(30, 50, 200, 30);
		value.setBounds(30, 80, 100, 30);
		pane.add(slide);
		pane.add(labe);
		pane.add(value);
		getContentPane().add(pane);
		OpenImage();
	}

	public static void main(String[] args) {
		SlideInt frame = new SlideInt ();
		frame.setTitle ("Test");
		frame.setBounds(100, 100, 180, 200);
		frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}


このコードでは、下記の部分で

//スライダーのノブを動かした時のイベント
	public void stateChanged (ChangeEvent e) {

		labe.setText("Val = " + slide.getValue());

		//輝度値を変える
		for (int i = 0; i < w*h; i++) {
			if (img.getRaster().getDataBuffer().getElem(i) < slide.getValue()) {
				img1.getRaster().getDataBuffer().setElem(i, slide.getValue());
			} else {
				img1.getRaster().getDataBuffer().setElem(i, img.getRaster().getDataBuffer().getElem(i));
			}
		}
	mypane1.repaint();
	}

JSliderの値よりも画像の輝度が小さい部分の輝度を、JSliderの値に変換している。
また、輝度値を変える用の画像"img1"と、参照用の画像"img"を用意することで画像を元に戻せるようにしている。


ここで開いた画像は16bitのため、下記の部分で

slide = new JSlider (0, 64000); //開いた画像が16bitなので、この値に設定

JSliderの範囲を“0~64000”に設定している。

また、輝度値の確認のために、

	//確認用にマウスを置いたポイントの輝度値を取得し、表示
	class MouseCheck extends MouseInputAdapter {
		public void mouseMoved (MouseEvent me) {
			x0 = me.getX();
			y0 = me.getY();
			value.setText(String.valueOf(img1.getRaster().getDataBuffer().getElem(y0*w + x0)));
		}
	}

も盛り込んだ。

JSliderとイベントを連動させるためには、
(1) ChangeListenerのimplements
(2) public void stateChanged (ChangeEvent e) {}の作成
(3) slide.addChangeListener (this); の設定
の3点が必要となる。

次回は、このコードを改良してもう少し使えそうなコードを書く予定。