package au.com.acpfg.io.pngwriter;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import org.knime.core.data.DataCell;
import org.knime.core.data.DataColumnSpec;
import org.knime.core.data.DataColumnSpecCreator;
import org.knime.core.data.DataRow;
import org.knime.core.data.DataTableSpec;
import org.knime.core.data.RowIterator;
import org.knime.core.data.RowKey;
import org.knime.core.data.def.DefaultRow;
import org.knime.core.data.def.DoubleCell;
import org.knime.core.data.def.IntCell;
import org.knime.core.data.def.StringCell;
import org.knime.core.data.image.png.PNGImageBlobCell;
import org.knime.core.data.image.png.PNGImageCell;
import org.knime.core.node.BufferedDataContainer;
import org.knime.core.node.BufferedDataTable;
import org.knime.core.node.CanceledExecutionException;
import org.knime.core.node.defaultnodesettings.SettingsModelColumnName;
import org.knime.core.node.defaultnodesettings.SettingsModelIntegerBounded;
import org.knime.core.node.defaultnodesettings.SettingsModelString;
import org.knime.core.node.ExecutionContext;
import org.knime.core.node.ExecutionMonitor;
import org.knime.core.node.InvalidSettingsException;
import org.knime.core.node.NodeLogger;
import org.knime.core.node.NodeModel;
import org.knime.core.node.NodeSettingsRO;
import org.knime.core.node.NodeSettingsWO;
/**
* This is the model implementation of PNGImageWriter.
* Writes PNGImageCell's to disk as separate files, based on user configuration. Ideal for saving graphical results from other nodes to files which can then be edited...
*
* @author http://www.plantcell.unimelb.edu.au
*/
public class PNGImageWriterNodeModel extends NodeModel {
// the logger instance
private static final NodeLogger logger = NodeLogger
.getLogger(PNGImageWriterNodeModel.class);
/** the settings key which is used to retrieve and
store the settings (from the dialog or from a settings file)
(package visibility to be usable from the dialog). */
static final String CFGKEY_FOLDER = "folder-to-save-to";
static final String CFGKEY_FILENAME_COL = "filename-column";
static final String CFGKEY_PNG_COL = "png-image-column";
// example value: the models count variable filled from the dialog
// and used in the models execution method. The default components of the
// dialog work with "SettingsModels".
private final SettingsModelString m_folder = new SettingsModelString(CFGKEY_FOLDER, "c:/temp");
private final SettingsModelColumnName m_filename_col = new SettingsModelColumnName(CFGKEY_FILENAME_COL, "");
private final SettingsModelString m_png_col = new SettingsModelString(CFGKEY_PNG_COL, "");
/**
* Constructor for the node model.
*/
protected PNGImageWriterNodeModel() {
super(1, 0);
}
/**
* {@inheritDoc}
*/
@Override
protected BufferedDataTable[] execute(final BufferedDataTable[] inData,
final ExecutionContext exec) throws Exception {
int n_rows = inData[0].getRowCount();
File folder = new File(m_folder.getStringValue());
int png_col_idx = inData[0].getDataTableSpec().findColumnIndex(m_png_col.getStringValue());
if (png_col_idx < 0) {
throw new Exception("Cannot find column: "+m_png_col.getStringValue()+", re-configure the node?");
}
boolean use_row_id = m_filename_col.useRowID();
int filename_idx = inData[0].getDataTableSpec().findColumnIndex(m_filename_col.getStringValue());
if (!use_row_id && filename_idx < 0) {
throw new Exception("Cannot find column: "+m_filename_col.getStringValue()+", re-configure the node?");
}
RowIterator it = inData[0].iterator();
while (it.hasNext()) {
DataRow r = it.next();
DataCell png_cell = r.getCell(png_col_idx);
if (png_cell == null || png_cell.isMissing())
continue;
String fname;
if (use_row_id) {
fname = r.getKey().getString();
} else {
DataCell fname_cell = r.getCell(filename_idx);
if (fname_cell == null || fname_cell.isMissing()) {
logger.warn("Ignoring row "+r.getKey().getString()+" as it has no filename");
continue;
}
fname = fname_cell.toString();
}
if (!fname.toLowerCase().endsWith(".png")) {
fname += ".png";
}
byte[] img_bytes;
if (png_cell instanceof PNGImageBlobCell) {
PNGImageBlobCell image_cell = (PNGImageBlobCell) png_cell;
img_bytes = image_cell.getImageContent().getByteArray();
} else if (png_cell instanceof PNGImageCell) {
PNGImageCell image_cell = (PNGImageCell) png_cell;
img_bytes = image_cell.getImageContent().getByteArray();
} else {
throw new Exception("Unknown image type: "+png_cell);
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(m_folder.getStringValue(), fname)));
bos.write(img_bytes);
bos.close();
img_bytes = null;
}
return new BufferedDataTable[]{};
}
/**
* {@inheritDoc}
*/
@Override
protected void reset() {
}
/**
* {@inheritDoc}
*/
@Override
protected DataTableSpec[] configure(final DataTableSpec[] inSpecs)
throws InvalidSettingsException {
return new DataTableSpec[]{};
}
/**
* {@inheritDoc}
*/
@Override
protected void saveSettingsTo(final NodeSettingsWO settings) {
m_folder.saveSettingsTo(settings);
m_filename_col.saveSettingsTo(settings);
m_png_col.saveSettingsTo(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void loadValidatedSettingsFrom(final NodeSettingsRO settings)
throws InvalidSettingsException {
m_folder.loadSettingsFrom(settings);
m_filename_col.loadSettingsFrom(settings);
m_png_col.loadSettingsFrom(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void validateSettings(final NodeSettingsRO settings)
throws InvalidSettingsException {
m_folder.validateSettings(settings);
m_filename_col.validateSettings(settings);
m_png_col.validateSettings(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void loadInternals(final File internDir,
final ExecutionMonitor exec) throws IOException,
CanceledExecutionException {
}
/**
* {@inheritDoc}
*/
@Override
protected void saveInternals(final File internDir,
final ExecutionMonitor exec) throws IOException,
CanceledExecutionException {
}
}