package org.openlca.io;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import org.openlca.core.math.IMatrix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Exports a matrix as an image file. Cells with values are displayed in another
* column than blank cells. This can be helpful to analyze the structure of a
* matrix.
*/
public class MatrixImageExport {
private int width = -1;
private int height = -1;
private Logger log = LoggerFactory.getLogger(getClass());
private IMatrix matrix;
private File exportFile;
public MatrixImageExport(IMatrix matrix, File exportFile) {
this.matrix = matrix;
this.exportFile = exportFile;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public void run() {
log.trace("write matrix to image {}", exportFile);
int colWidth = colWidth();
int rowHeight = rowHeight();
int realWidth = matrix.columns() * colWidth;
int realHeight = matrix.rows() * rowHeight;
BufferedImage image = new BufferedImage(realWidth, realHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, realWidth, realHeight);
graphics.setColor(Color.BLUE);
try {
drawCells(graphics, colWidth, rowHeight);
ImageIO.write(image, "png", exportFile);
} catch (Exception e) {
log.error("Failed to write matrix to image", e);
}
}
private void drawCells(Graphics2D graphics, int colWidth, int rowHeight) {
for (int row = 0; row < matrix.rows(); row++) {
for (int col = 0; col < matrix.columns(); col++) {
double val = matrix.get(row, col);
if (val == 0)
continue;
if (val < 0)
graphics.setColor(Color.RED);
else
graphics.setColor(Color.BLUE);
graphics.fillRect(col * colWidth, row * rowHeight, colWidth,
rowHeight);
}
}
}
private int colWidth() {
int cols = matrix.columns();
if (width != -1) {
int w = width / cols;
return w == 0 ? 1 : w;
}
if (cols > 1000)
return 1;
if (cols > 500)
return 2;
int w = 500 / cols;
return w < 2 ? 2 : w;
}
private int rowHeight() {
int rows = matrix.rows();
if (height != -1) {
int h = height / rows;
return h == 0 ? 1 : h;
}
if (rows > 1000)
return 1;
if (rows > 500)
return 2;
int h = 500 / rows;
return h < 2 ? 2 : h;
}
}