Reputation: 1123
I am new for java. I have 2D binary matrix with only 1s and 0s now. I want to save it as jpg image(black and white) with same width and height. How could I realize that? I tried the code below but failed, saying "java.lang.IllegalArgumentException: image == null!" Please help me with that or give me your better solution. Thank you very much.
public static void main(String[] args) throws IOException {
//result is double[25][33] binary matrix with only 1s and 0s;
int height=result.length;
int width=result[0].length;;
byte[] data = new byte[height*width];
int k=0;
for(int i = 0;i < height;i++){
for(int j = 0; j < width; j++){
data[k]=(byte)result[i][j];
k++;
}
System.out.print("\n");
}
InputStream input = new ByteArrayInputStream(data);
BufferedImage output = ImageIO.read(input);
ImageIO.write(ouput, "jpg", new File("c:/result.jpg"));
}
Upvotes: 6
Views: 6331
Reputation: 4845
JHeatChart
does this job as well without you having to create a custom image library.
// Create some dummy data.
double[][] data = new double[][]{{3,2,3,4,5,6},
{2,3,4,5,6,7},
{3,4,5,6,7,6},
{4,5,6,7,6,5}};
// Step 1: Create our heat map chart using our data.
HeatChart map = new HeatChart(data);
// Step 2: Customise the chart.
map.setTitle("This is my heat chart title");
map.setXAxisLabel("X Axis");
map.setYAxisLabel("Y Axis");
// Step 3: Output the chart to a file.
map.saveToFile(new File("java-heat-chart.png"));
What you are essentially trying to do is make a heat map. And instead of a range of values ranging from 0 to whatever, you have a range of 0 and 1.
Replace double[][] data = new double[][](//etc);
with your boolean array.
Upvotes: 1
Reputation: 47078
This is a simple example that creates a 30x30 checkered box:
public static void main(String... args) throws IOException {
int w = 30, h = 30;
// create the binary mapping
byte BLACK = (byte)0, WHITE = (byte)255;
byte[] map = {BLACK, WHITE};
IndexColorModel icm = new IndexColorModel(1, map.length, map, map, map);
// create checkered data
int[] data = new int[w*h];
for(int i=0; i<w; i++)
for(int j=0; j<h; j++)
data[i*h + j] = i%4<2 && j%4<2 || i%4>=2 && j%4>=2 ? BLACK:WHITE;
// create image from color model and data
WritableRaster raster = icm.createCompatibleWritableRaster(w, h);
raster.setPixels(0, 0, w, h, data);
BufferedImage bi = new BufferedImage(icm, raster, false, null);
// output to a file
ImageIO.write(bi, "jpg", new File("C:\\Users\\user\\Desktop\\test.jpg"));
}
EDIT:
For what you are doing you actually don't need to create your own ImageColorModel, you can use a built in type: BufferedImage.TYPE_BYTE_GRAY or TYPE_BYTE_BINARY. Here is a better example and shows how to use grayscale to get a checkered box:
public static void main(String... args) throws IOException {
int w = 40, h = 40, divs = 5;
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
WritableRaster raster = bi.getRaster();
for(int i=0; i<w; i++)
for(int j=0; j<h; j++)
raster.setSample(i,j,0,128+(int)(127*Math.sin(Math.PI*i/w*divs)*Math.sin(Math.PI*j/h*divs)));
ImageIO.write(bi, "jpg", new File("C:\\Users\\user\\Desktop\\test.jpg"));
}
Upvotes: 4