Skip to content
Snippets Groups Projects
Commit fb251c9d authored by Lennart Eichhorn's avatar Lennart Eichhorn
Browse files

Video generation is now done by a visualizer.

parent 9a03874b
No related branches found
No related tags found
No related merge requests found
...@@ -14,6 +14,7 @@ import Selectors.Tournament; ...@@ -14,6 +14,7 @@ import Selectors.Tournament;
import Visualization.Visualizers.BestFoldingToConsole; import Visualization.Visualizers.BestFoldingToConsole;
import Visualization.Visualizers.BestFoldingToImage; import Visualization.Visualizers.BestFoldingToImage;
import Visualization.Visualizers.BestFoldingsToVideo;
import Visualization.Visualizers.GenerationOverviewToConsole; import Visualization.Visualizers.GenerationOverviewToConsole;
import Visualization.Visualizers.GenerationProgressToLog; import Visualization.Visualizers.GenerationProgressToLog;
import java.io.IOException; import java.io.IOException;
...@@ -92,6 +93,9 @@ public class GeneticAlgorithm { ...@@ -92,6 +93,9 @@ public class GeneticAlgorithm {
}else if (vm.equals(VisualizerMethods.Generation)) { }else if (vm.equals(VisualizerMethods.Generation)) {
this.visualizers[j] = new GenerationOverviewToConsole(isHydrophobic, config); this.visualizers[j] = new GenerationOverviewToConsole(isHydrophobic, config);
j++; j++;
}else if (vm.equals(VisualizerMethods.Video)) {
this.visualizers[j] = new BestFoldingsToVideo(config);
j++;
} }
} }
......
...@@ -16,14 +16,5 @@ public class Main { ...@@ -16,14 +16,5 @@ public class Main {
GeneticAlgorithm ga = new GeneticAlgorithm(protein, config); GeneticAlgorithm ga = new GeneticAlgorithm(protein, config);
ga.simulateGenerations(); ga.simulateGenerations();
// Create a new video if possible and desired
boolean imagesRefreshed = Arrays.asList(config.getVisualizers()).contains(VisualizerMethods.Image);
boolean videoEnabled = Arrays.asList(config.getVisualizers()).contains(VisualizerMethods.Video);
if (imagesRefreshed && videoEnabled){
String videoPath = config.getVideoDirectory() + "/" + config.getJobName() + ".mp4";
VideoCreator.createVideo(config.getImageSequenceDirectory(), videoPath,
config.getImageFps(), config.getImagesToFpsIncrease(), config.getImageFpsMax(),
ga.getMaxH(), ga.getMaxW(), config.isZoom());
}
} }
} }
...@@ -41,7 +41,7 @@ import java.util.List; ...@@ -41,7 +41,7 @@ import java.util.List;
*/ */
public class JCodecPNGtoMP4 { public class JCodecPNGtoMP4 {
static void sortByNumber(File[] files) { public static void sortByNumber(File[] files) {
Arrays.sort(files, new Comparator<File>() { Arrays.sort(files, new Comparator<File>() {
@Override @Override
public int compare(File o1, File o2) { public int compare(File o1, File o2) {
...@@ -64,7 +64,7 @@ public class JCodecPNGtoMP4 { ...@@ -64,7 +64,7 @@ public class JCodecPNGtoMP4 {
}); });
} }
static void generateVideoBySequenceImages(File videoFile, String pathImages, String imageExt, public static void generateVideoBySequenceImages(File videoFile, String pathImages, String imageExt,
int fps, int imgToFpsIncrease, int maxFps) throws Exception { int fps, int imgToFpsIncrease, int maxFps) throws Exception {
SeekableByteChannel out = null; SeekableByteChannel out = null;
try { try {
......
package Visualization.Visualizers;
import Interfaces.Visualizer;
import MainClasses.Candidate;
import MainClasses.Config;
import MainClasses.GeneticAlgorithm;
import Visualization.JCodecPNGtoMP4;
import Visualization.VideoCreator;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
public class BestFoldingsToVideo implements Visualizer {
Config config;
private final int MAXIMUM_SIZE;
private final FilenameFilter imageFilter;
public BestFoldingsToVideo(Config config){
this.config = config;
MAXIMUM_SIZE = 3000;
imageFilter = new FilenameFilter() {
@Override
public boolean accept(final File dir, String name) {
for (final String ext : new String[]{"jpg", "png"}) {
if (name.endsWith("." + ext) && name.startsWith(config.getJobName())) {
return (true);
}
}
return (false);
}
};
try {
Files.createDirectories(Paths.get(config.getVideoDirectory()));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void drawProtein(Candidate[] generation, GeneticAlgorithm geneticAlgorithm) {
//TODO Only render video for the last generation
if(geneticAlgorithm.generation == config.getTotalGenerations()-2){
String filename = config.getLogfileDirectory() + "/" + config.getJobName() + ".mp4";
createVideo(
config.getImageSequenceDirectory(),
filename,
config.getImageFps(),
config.getImagesToFpsIncrease(),
config.getImageFpsMax(),
geneticAlgorithm.getMaxH(),
geneticAlgorithm.getMaxW(),
config.isZoom()
);
}
}
public void createVideo(String imagesPath, String videoPathAndFile,
int imgFps, int imgToFpsIncrease, int maxFps, int maxH, int maxW, boolean zoom) {
try {
System.err.println("\nStarting image resizing");
if (zoom) {
resizeImagesWithZoom(imagesPath);
} else {
resizeImages(imagesPath, maxH, maxW);
}
File videoFile = new File(videoPathAndFile);
if (!videoFile.exists()) {
videoFile.createNewFile();
}
try {
JCodecPNGtoMP4.generateVideoBySequenceImages(videoFile, imagesPath, "png", imgFps, imgToFpsIncrease, maxFps);
} catch (Exception e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void resizeImages(String imagesPath, int maxH, int maxW) throws IOException {
File dir = new File(imagesPath);
if (dir.isDirectory()) {
// reads input images and determines maximum required size
int maxHeight = maxH;
int maxWidth = maxW;
if (maxHeight <= 0 || maxWidth <= 0) {
int counter = 1;
for (final File f : dir.listFiles(imageFilter)) {
BufferedImage inputImage = ImageIO.read(f);
if (maxHeight < inputImage.getHeight()) {
maxHeight = inputImage.getHeight();
}
if (maxWidth < inputImage.getWidth()) {
maxWidth = inputImage.getWidth();
}
}
}
// Needed because video is not playable with bigger sizes, mostly a concern for straight line initialization
if (maxWidth > MAXIMUM_SIZE) {
maxWidth = MAXIMUM_SIZE;
}
if (maxHeight > MAXIMUM_SIZE) {
maxHeight = MAXIMUM_SIZE;
}
// Resizes all images
for (final File f : dir.listFiles(imageFilter)) {
BufferedImage inputImage = ImageIO.read(f);
// creates output image
BufferedImage outputImage = new BufferedImage(maxWidth,
maxHeight, inputImage.getType());
// draws input image to the top left corner
Graphics2D g2d = outputImage.createGraphics();
//TODO The following two lines should be unnecessary
//g2d.setColor(Config.imageBackground);
//g2d.fillRect(0,0, maxWidth, maxHeight);
g2d.drawImage(inputImage, 0, 0, inputImage.getWidth(), inputImage.getHeight(), null);
g2d.dispose();
// overwrites image
ImageIO.write(outputImage, "png", f);
}
}
}
private void resizeImagesWithZoom(String imagesPath) throws IOException {
File dir = new File(imagesPath);
int[] maxHeightAfterIndex = new int[dir.listFiles(imageFilter).length];
int[] maxWidthAfterIndex = new int[dir.listFiles(imageFilter).length];
if (dir.isDirectory()) {
Path directoryPath = Paths.get(new File(imagesPath).toURI());
DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath, "*.png");
List<File> filesList = new ArrayList<>();
for (Path path : stream) {
filesList.add(path.toFile());
}
File[] files = new File[filesList.size()];
filesList.toArray(files);
JCodecPNGtoMP4.sortByNumber(files);
List<Object> list = Arrays.asList(files);
Collections.reverse(list);
list.toArray(files);
// reads input images and determines maximum required size after that particular image
int currentMaxHeight = 0;
int currentMaxWidth = 0;
int counter = files.length - 1;
for (File f : files) {
BufferedImage inputImage = ImageIO.read(f);
if (currentMaxHeight < inputImage.getHeight()) {
currentMaxHeight = inputImage.getHeight();
}
if (currentMaxWidth < inputImage.getWidth()) {
currentMaxWidth = inputImage.getWidth();
}
maxHeightAfterIndex[counter] = currentMaxHeight;
maxWidthAfterIndex[counter] = currentMaxWidth;
counter--;
}
// Resizes all images
counter = files.length - 1;
for (final File f : files) {
BufferedImage inputImage = ImageIO.read(f);
// creates output image
BufferedImage outputImage = new BufferedImage(maxWidthAfterIndex[0], // Total maximum W/H
maxHeightAfterIndex[0], inputImage.getType());
// draws input image to the top left corner
Graphics2D g2d = outputImage.createGraphics();
//TODO The following two lines should be unnecessary
//g2d.setColor(Config.imageBackground);
//g2d.fillRect(0,0, maxWidthAfterIndex[0], maxHeightAfterIndex[0]);
int newHeight = 0;
int newWidth = 0;
// Width expansion to border if height fits accordingly
double expansionByWidth = (double) maxWidthAfterIndex[0] / maxWidthAfterIndex[counter];
if (maxHeightAfterIndex[counter] * expansionByWidth <= maxHeightAfterIndex[0]) {
newWidth = (int) Math.floor(inputImage.getWidth() * expansionByWidth);
newHeight = (int) Math.floor(inputImage.getHeight() * expansionByWidth);
} else {
// otherwise height expansion to border and width according to ratio
double expansionByHeight = (double) maxHeightAfterIndex[0] / maxHeightAfterIndex[counter];
newWidth = (int) Math.floor(inputImage.getWidth() * expansionByHeight);
newHeight = (int) Math.floor(inputImage.getHeight() * expansionByHeight);
}
g2d.drawImage(inputImage, 0, 0, newWidth, newHeight, null);
g2d.dispose();
// overwrites image
ImageIO.write(outputImage, "png", f);
counter--;
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment