aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/Helper.java
blob: b7a139ab79780d7d72ea19624509c0b3f6d791f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * Provide simple tools to read, write and show pictures.
 */
public final class Helper {

    // Convert specified BufferedImage into an array
    private static int[][] fromBufferedImage(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        int[][] array = new int[height][width];
        for (int row = 0; row < height; ++row) {
            for (int col = 0; col < width; ++col) {
                array[row][col] = image.getRGB(col, row);
            }
        }
        return array;
    }

    // Convert specified array int a BufferedImage
    private static BufferedImage toBufferedImage(int[][] array) {
        int width = array[0].length;
        int height = array.length;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int row = 0; row < height; ++row) {
            for (int col = 0; col < width; ++col) {
                image.setRGB(col, row, array[row][col]);
            }
        }
        return image;
    }

    /**
     * Reads specified image from disk.
     *
     * @param path Input file path
     * @return HxW array of packed RGB colors, or <code>null</code> on failure
     * @see #write
     */
    public static int[][] read(String path) {
        try {
            BufferedImage image = ImageIO.read(new File(path));
            return fromBufferedImage(image);
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * Writes specified image to disk.
     *
     * @param path  Output file path
     * @param array HxW array of packed RGB colors
     * @return {@code true} if write operation was successful, {@code false} otherwise
     * @see #read
     */
    public static boolean write(String path, int[][] array) {

        // Convert array to Java image
        BufferedImage image = toBufferedImage(array);

        // Get desired file format
        int index = path.lastIndexOf('.');
        if (index < 0)
            return false;
        String extension = path.substring(index + 1);

        // Export image
        try {
            return ImageIO.write(image, extension, new File(path));
        } catch (IOException e) {
            return false;
        }

    }

    /**
     * Shows specified image in a window.
     *
     * @param array HxW array of packed RGB colors
     * @param title title to be displayed
     */
    public static void show(int[][] array, String title) {

        // Convert array to Java image
        final BufferedImage image = toBufferedImage(array);

        // Create a panel to render this image
        @SuppressWarnings("serial")
        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(image, 0, 0, getWidth(), getHeight(), null, null);
            }
        };

        // Create a frame to hold this panel
        final JFrame frame = new JFrame(title);
        frame.add(panel);
        frame.pack();
        frame.setSize(image.getWidth(), image.getHeight());

        // Register closing event
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                frame.setVisible(false);
                synchronized (frame) {
                    frame.notifyAll();
                }
            }
        });

        // Show this frame
        frame.setVisible(true);

        // Wait for close operation
        try {
            synchronized (frame) {
                while (frame.isVisible())
                    frame.wait();
            }
        } catch (InterruptedException e) {
            // Empty on purpose
        }
        frame.dispose();

    }

}