1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.examples.kmeans.image;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.UncheckedIOException;
23 import java.util.List;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.awt.image.BufferedImage;
28 import java.awt.image.Raster;
29 import java.awt.image.WritableRaster;
30 import org.apache.commons.imaging.Imaging;
31 import org.apache.commons.imaging.ImageFormat;
32 import org.apache.commons.imaging.ImageFormats;
33 import org.apache.commons.imaging.ImageReadException;
34 import org.apache.commons.imaging.ImageWriteException;
35 import org.apache.commons.math4.legacy.ml.clustering.Clusterable;
36 import org.apache.commons.math4.legacy.ml.clustering.Cluster;
37
38
39
40
41 final class ImageData {
42
43 private final Raster data;
44
45 private final List<PixelClusterable> pixels = new ArrayList<>();
46
47
48
49
50 private ImageData(BufferedImage image) {
51 data = image.getData();
52
53
54 for (int row = 0; row < image.getHeight(); row++) {
55 for (int col = 0; col < image.getWidth(); col++) {
56 pixels.add(new PixelClusterable(col, row));
57 }
58 }
59 }
60
61
62
63
64
65
66
67 static ImageData load(String file) {
68 try {
69 return new ImageData(Imaging.getBufferedImage(new File(file)));
70 } catch (IOException e) {
71 throw new UncheckedIOException(e);
72 } catch (ImageReadException e) {
73 throw new RuntimeException(e);
74 }
75 }
76
77
78
79
80
81
82
83
84 void write(List<? extends Cluster<PixelClusterable>> clusters,
85 String outputPrefix) {
86 final BufferedImage imageC = new BufferedImage(data.getWidth(),
87 data.getHeight(),
88 BufferedImage.TYPE_INT_RGB);
89
90 final WritableRaster raster = imageC.getRaster();
91
92 for (Cluster<PixelClusterable> cluster : clusters) {
93 final double[] color = cluster.centroid().getPoint();
94 for (PixelClusterable pixel : cluster.getPoints()) {
95 raster.setPixel(pixel.x, pixel.y, color);
96 }
97 }
98
99 try {
100 final ImageFormat format = ImageFormats.PNG;
101 Imaging.writeImage(imageC,
102 new File(outputPrefix + format.getDefaultExtension()),
103 format);
104 } catch (IOException e) {
105 throw new UncheckedIOException(e);
106 } catch (ImageWriteException e) {
107 throw new RuntimeException(e);
108 }
109 }
110
111
112
113
114 Collection<PixelClusterable> getPixels() {
115 return Collections.unmodifiableCollection(pixels);
116 }
117
118
119
120
121
122
123 class PixelClusterable implements Clusterable {
124
125 private final int x;
126
127 private final int y;
128
129 private double[] color;
130
131
132
133
134
135 PixelClusterable(int x,
136 int y) {
137 this.x = x;
138 this.y = y;
139 this.color = null;
140 }
141
142
143 @Override
144 public double[] getPoint() {
145 if (color == null) {
146 color = data.getPixel(x, y, (double[]) null);
147 }
148 return color;
149 }
150 }
151 }