概要
JavaのBufferedImageを使って画像をモノクロ化してみましょう!画像の読み込みはImageIOで行えます。ImageIOのreadメソッドにFileオブジェクトを渡すとBufferedImageが返ってきます。この処理は以下のように書けます。(ここではあえて型推論を使わず型を明示的に書いています。)
BufferedImage image = ImageIO.read(new File("image.jpg"));
画像のモノクロ化
画像をモノクロ化する方法はいくつかありますが、今回は各ピクセルの光りの三原色である赤、緑、青の値を足して3で割ったものを赤、緑、青にそれぞれを割り当てる方法をとります、
ソースコード
import javax.swing.JFrame; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JFileChooser; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JMenuBar; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import java.awt.Graphics; import java.awt.Dimension; import java.awt.event.InputEvent; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import java.util.Optional; import java.io.IOException; public class MonoImageSample extends JComponent{ private Optional<BufferedImage> monoImage; public static void main(String... args){ SwingUtilities.invokeLater(MonoImageSample::start); } private static void start(){ var frame = new JFrame(); var sample = new MonoImageSample(); var scroll = new JScrollPane(sample); var menubar = new JMenuBar(); var fileMenu = menubar.add(new JMenu("ファイル(F)")); fileMenu.setMnemonic('F'); var openItem = fileMenu.add(new JMenuItem("開く(O)", 'O')); openItem.setAccelerator(KeyStroke.getKeyStroke('O', InputEvent.CTRL_DOWN_MASK)); openItem.addActionListener(e -> { var fileChooser = new JFileChooser(); if(fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION){ try{ sample.load(fileChooser.getSelectedFile()); }catch(IOException ex){ JOptionPane.showMessageDialog(frame, "ファイルの読み込みに失敗しました", "エラー", JOptionPane.ERROR_MESSAGE); ex.printStackTrace(); } } }); scroll.setPreferredSize(new Dimension(600, 500)); frame.add(scroll); frame.setJMenuBar(menubar); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); } public MonoImageSample(){ monoImage = Optional.empty(); } public void load(File file) throws IOException{ //画像ファイルを読み込みモノクロ画像用のBufferedImaageを用意する var image = ImageIO.read(file); var dstImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType()); monoImage = Optional.of(dstImage); for(int y = 0; y < image.getHeight(); y++){ for(int x = 0; x < image.getWidth(); x++){ int rgb = image.getRGB(x, y); //RGBをそれぞれ取り出す int r = (rgb >> 16) & 0xFF; int g = (rgb >> 8) & 0xFF; int b = rgb & 0xFF; //RGBの和を3で割ったものをRGBのそれぞれの値とする int mono = (r + g + b) / 3; dstImage.setRGB(x, y, 0xFF000000 | (mono << 16) | (mono << 8) | mono); } } setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); repaint(); } @Override public void paintComponent(Graphics g){ monoImage.ifPresent(image -> g.drawImage(image, 0, 0, this)); } }
実行結果
実行した時点では何も表示されないのでメニューバーのファイルメニューから開くを選んで画像を選んでみてください。そうすると以下のようにモノクロ画像が表示されます