Skip to content

Commit

Permalink
Merge pull request #289 from simlu/develop
Browse files Browse the repository at this point in the history
New Sliced Exporter
  • Loading branch information
simlu authored Aug 9, 2018
2 parents 50866d1 + faa8dfa commit cbce77f
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 1 deletion.
81 changes: 81 additions & 0 deletions src/main/java/com/vitco/app/export/SlicesExporter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.vitco.app.export;

import com.vitco.app.core.data.Data;
import com.vitco.app.core.data.container.Voxel;
import com.vitco.app.layout.content.console.ConsoleInterface;
import com.vitco.app.util.components.progressbar.ProgressDialog;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
* Export cross-section slices of the voxel into
* series of bitmap files.
*/
public class SlicesExporter extends AbstractExporter {

public SlicesExporter(File exportTo, Data data, ProgressDialog dialog, ConsoleInterface console) throws IOException {
super(exportTo, data, dialog, console);
}

private int ax1 = -1;
private int ax2 = -1;
private int ax3 = -1;
public void setSliceDirection(String sliceAxis) {
ax1 = sliceAxis.charAt(0) - 120; // x = 0, y = 1, z = 2
ax2 = sliceAxis.equals("x") ? 2 : 0;
ax3 = sliceAxis.equals("y") ? 2 : 1;
}

private String exportFormat = "png";
public void setExportFormat(String format) {
this.exportFormat = format;
}

private boolean invertOrder = false;
public void setInvertOrder(boolean invert) {
this.invertOrder = invert;
}

// allow explicit access since multiple files are generated
public boolean generateImages() throws IOException {
int[] size = getSize();
int nSlices = size[ax1]; // number of slices
int width = size[ax2]; // width of slice bitmaps
int height = size[ax3]; // height of slice bitmaps

// create images
BufferedImage[] slices = new BufferedImage[nSlices];
for (int idx = 0; idx < nSlices; idx++) {
slices[idx] = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}

// paint images
int[] min = getMin();
for (Voxel voxel : this.data.getVisibleLayerVoxel()) {
int[] pos = voxel.getPosAsInt();
slices[pos[ax1] - min[ax1]].setRGB(pos[ax2] - min[ax2], pos[ax3] - min[ax3], voxel.getColor().getRGB());
}

// save images
for (int idx = 0; idx < nSlices; idx++) {
String fileName = String.format(
"%s_%d.%s",
exportTo.getAbsolutePath(),
invertOrder ? slices.length - idx : idx + 1,
exportFormat
);
System.out.println("Creating file: " + fileName);
ImageIO.write(slices[idx], exportFormat, new File(fileName));
}

return true; // success
}

@Override
protected boolean writeFile() {
throw new UnsupportedOperationException("Not implemented yet");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -631,9 +631,38 @@ protected Object doInBackground() throws Exception {

// ---------------

// add bitmap slices exporter
FieldSet slicesExporter = new FieldSet("slices_format", "Sliced model (png/gif)");
// add information for the exporter
LabelModule slicesInfo = new LabelModule("Info: Generates series of bitmap images. Each image corresponds to "
+ "cross-section of visible voxels at each coordinate of selected axis.\nImportant: Can generate a large "
+ "number of files!");
slicesExporter.addComponent(slicesInfo);
slicesExporter.addComponent(new SeparatorModule("Slice Along"));
slicesExporter.addComponent(new SeparatorModule("Slice Along"));
ComboBoxModule sliceAxis = new ComboBoxModule("axis", new String[][]{
new String[]{"x", "x-axis"},
new String[]{"y", "y-axis"},
new String[]{"z", "z-axis"}
}, 0);
slicesExporter.addComponent(sliceAxis);

slicesExporter.addComponent(new SeparatorModule("Output Format"));
ComboBoxModule formatSelect = new ComboBoxModule("export_format", new String[][]{
new String[]{"png", "*.png"},
new String[]{"gif", "*.gif"},
}, 0);
slicesExporter.addComponent(formatSelect);
slicesExporter.addComponent(new SeparatorModule("Misc"));
slicesExporter.addComponent(new CheckBoxModule("invert", "Invert direction", false));
LabelModule invertInfo = new LabelModule("This option effectively inverts order of the numbers in file names.");
slicesExporter.addComponent(invertInfo);

// ---------------

// add all formats
dialog.addComboBox("export_type", new FieldSet[] {
collada, magicaVoxelExporter, voxVoxLapExporter, kv6Exporter, pnxExporter, qbExporter, imageRenderer
collada, magicaVoxelExporter, voxVoxLapExporter, kv6Exporter, pnxExporter, qbExporter, slicesExporter, imageRenderer
}, 0);

// ---------------
Expand Down Expand Up @@ -1112,6 +1141,49 @@ protected Object doInBackground() throws Exception {

// ===========
}
else if (dialog.is("export_type=slices_format")) {

// ===========
// -- handle sliced file format

// create progress dialog
final ProgressDialog progressDialog = new ProgressDialog(frame);

// do the exporting
progressDialog.start(new ProgressWorker() {
@Override
protected Object doInBackground() {

final File exportTo = new File(baseName);

// export sliced files format
boolean success;
long time = System.currentTimeMillis();
try {
SlicesExporter exporter = new SlicesExporter(exportTo, data, progressDialog, console);
exporter.setSliceDirection(dialog.getValue("slices_format.axis"));
exporter.setExportFormat(dialog.getValue("slices_format.export_format"));
exporter.setInvertOrder(dialog.is("slices_format.invert=true"));

success = exporter.generateImages();
} catch (IOException ignored) {
success = false;
}
if (success) {
console.addLine(
String.format(langSelector.getString("export_file_successful"),
System.currentTimeMillis() - time)
);
} else {
console.addLine(langSelector.getString("export_file_error"));
}

return null;
}
});

// ===========
}
// -----
// store serialization
preferences.storeObject("export_dialog_serialization", dialog.getSerialization());
Expand Down

0 comments on commit cbce77f

Please sign in to comment.