diff --git a/src/main/java/Enums/State.java b/src/main/java/Enums/State.java
new file mode 100644
index 0000000000000000000000000000000000000000..3193f10a203d8a9bc3d6068c17bce34ed3d42035
--- /dev/null
+++ b/src/main/java/Enums/State.java
@@ -0,0 +1,12 @@
+package Enums;
+
+public enum State {
+    Empty,
+    Hydrophobic,
+    Hydrophilic,
+    HydrophobicMulti,
+    HydrophilicMulti,
+    Mixed,
+    ConnectionVertical,
+    ConnectionHorizontal
+}
diff --git a/src/main/java/Interfaces/Visualizer.java b/src/main/java/Interfaces/Visualizer.java
index f93e288b9162a71a72e181d32872202f994d8e78..50dbf16ba7fdcfcbd12de2d221f30794f38cfb05 100644
--- a/src/main/java/Interfaces/Visualizer.java
+++ b/src/main/java/Interfaces/Visualizer.java
@@ -1,4 +1,91 @@
 package Interfaces;
 
+import Enums.State;
+import MainClasses.Vertex;
+import Visualization.Cell;
+
+import java.util.ArrayList;
+import java.util.List;
+
 public interface Visualizer {
+
+    void drawProtein(ArrayList<Vertex> vertexListOriginal, double fit, int bond, int over, int gen);
+
+    static ArrayList<Vertex> deepCopyVertexList (List<Vertex> vertexListOriginal) {
+        ArrayList<Vertex> vertexList = new ArrayList<>();
+        for (Vertex v : vertexListOriginal) {
+            Vertex vNew = new Vertex(v.x, v.y, v.isHydrophobic, v.outgoingDirection);
+            vertexList.add(vNew);
+        }
+        return vertexList;
+    }
+
+    static Cell[][] convertProteinTo2DArray(ArrayList<Vertex> vertexList) {
+        // Determine size
+        int minX = 0;
+        int maxX = 0;
+        int minY = 0;
+        int maxY = 0;
+        for (Vertex vertex : vertexList) {
+            if (vertex.x < minX) {
+                minX = vertex.x;
+            }
+            if (vertex.x > maxX) {
+                maxX = vertex.x;
+            }
+            if (vertex.y < minY) {
+                minY = vertex.y;
+            }
+            if (vertex.y > maxY) {
+                maxY = vertex.y;
+            }
+        }
+
+        // Fix min values to 0 and double vertex coordinates to make room for connections
+        maxX += Math.abs(minX);
+        maxY += Math.abs(minY);
+        for (Vertex vertex : vertexList) {
+            vertex.x += Math.abs(minX);
+            vertex.x *= 2;
+            vertex.y += Math.abs(minY);
+            vertex.y *= 2;
+        }
+
+        // Add vertexes and connections to 2d array
+        Cell[][] cellArray = new Cell[maxY * 2 + 1][maxX * 2 + 1];
+        for (int yIndex = 0; yIndex < maxY * 2 + 1; yIndex++) {
+            for (int xIndex = 0; xIndex < maxX * 2 + 1; xIndex++) {
+                cellArray[yIndex][xIndex] = new Cell();
+            }
+        }
+
+        for (int i = 0; i < vertexList.size(); i++) {
+            Vertex vertex = vertexList.get(i);
+            if (vertex.isHydrophobic) {
+                cellArray[vertex.y][vertex.x].addState(State.Hydrophobic);
+            } else {
+                cellArray[vertex.y][vertex.x].addState(State.Hydrophilic);
+            }
+            cellArray[vertex.y][vertex.x].addAminoIndex(i);
+
+            // Add connection, except on the last one
+            if (i + 1 != vertexList.size()) {
+                if (vertex.outgoingDirection == 0) {
+                    cellArray[vertex.y + 1][vertex.x].addState(State.ConnectionVertical);
+                } else if (vertex.outgoingDirection == 1) {
+                    cellArray[vertex.y][vertex.x + 1].addState(State.ConnectionHorizontal);
+                } else if (vertex.outgoingDirection == 2) {
+                    cellArray[vertex.y - 1][vertex.x].addState(State.ConnectionVertical);
+                } else if (vertex.outgoingDirection == 3) {
+                    cellArray[vertex.y][vertex.x - 1].addState(State.ConnectionHorizontal);
+                }
+            }
+        }
+
+        return cellArray;
+    }
+
+    void setFilename(String filename);
+    int getMaxH();
+    int getMaxW();
 }
diff --git a/src/main/java/MainClasses/Config.java b/src/main/java/MainClasses/Config.java
index 515e320959ff7bc643de9845488c6e733bdf0e62..42dbc7e4b2ab9ab926d43991d3f5325d93afb0aa 100644
--- a/src/main/java/MainClasses/Config.java
+++ b/src/main/java/MainClasses/Config.java
@@ -2,6 +2,7 @@ package MainClasses;
 
 import Enums.Selection;
 
+import java.awt.*;
 import java.io.BufferedInputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -25,6 +26,27 @@ public class Config {
     static int K; // Number of selected Candidates to face off in a tournament selection
     static String IMAGE_SEQUENCE_PATH;
 
+    // For images
+    public static final Font font = new Font("Sans-Serif", Font.PLAIN, 15);
+    public static final Color imageBackground = new Color(255, 255, 255);
+    public static final Color imageConnection = new Color(0, 0, 0);
+    public static final Color imageOutline = new Color(0, 0, 0);
+    public static final Color imageHydrophobic = new Color(205, 0, 0);
+    public static final Color imageHydrophilic = new Color(0, 0, 255);
+    public static final Color imageMixed = new Color(205, 0, 205);
+    public static final Color imageAminoText = new Color(0, 190, 190);
+    public static final Color imageText = new Color(0,0,0);
+
+    // For console output
+    public static final String consoleEmpty = "   ";
+    public static final String consoleHydrophobic = "(o)";
+    public static final String consoleHydrophilic = "(i)";
+    public static final String consoleHydrophobicMulti = "{o}";
+    public static final String consoleHydrophilicMulti = "{i}";
+    public static final String consoleMixed = "{z}";
+    public static final String consoleConnectionVertical = " | ";
+    public static final String consoleConnectionHorizontal = "---";
+
     // Points per hydrophobic bond
     static int POINTS_PER_BOND;
 
diff --git a/src/main/java/MainClasses/GeneticAlgorithm.java b/src/main/java/MainClasses/GeneticAlgorithm.java
index b6951761aab2e365ac4f868842664e7936bfbcb0..6ba204f0307813411c91dcf603d560c5a7e4019c 100644
--- a/src/main/java/MainClasses/GeneticAlgorithm.java
+++ b/src/main/java/MainClasses/GeneticAlgorithm.java
@@ -3,14 +3,12 @@ package MainClasses;
 import Enums.DirectionNESW;
 import Evaluators.EvaluatorNESW;
 import InitialGenerationCreators.Curl;
-import Interfaces.Evaluator;
-import Interfaces.InitialGenerationCreator;
-import Interfaces.Mutator;
-import Interfaces.Selector;
+import Interfaces.*;
 import Mutators.Crossover;
 import Mutators.SinglePoint;
 import Selectors.OnlyBest;
-import Visualization.ProteinDrawer;
+import Visualization.Visualizers.VisualizerNESWtoConsole;
+import Visualization.Visualizers.VisualizerNESWtoFile;
 
 import java.io.IOException;
 import java.nio.file.Files;
@@ -20,7 +18,7 @@ import java.util.Random;
 
 public class GeneticAlgorithm {
     Random rand = new Random();
-    ProteinDrawer pdraw;
+    Visualizer visualizer;
 
     int[] isHydrophobic;
     Candidate[] population;
@@ -40,7 +38,8 @@ public class GeneticAlgorithm {
     // Initialize with protein
     public GeneticAlgorithm (int[] protein) {
         this.isHydrophobic =  protein;
-        this.pdraw = new ProteinDrawer(Config.IMAGE_SEQUENCE_PATH);
+//        this.visualizer = new VisualizerNESWtoConsole();
+        this.visualizer = new VisualizerNESWtoFile(Config.IMAGE_SEQUENCE_PATH);
 
 //        this.initialGenCreator = new RandomDirection<>(this.rand, DirectionNESW.class);
 //        this.initialGenCreator = new StraightLine();
@@ -106,8 +105,8 @@ public class GeneticAlgorithm {
         int bonds = this.evaluator.evaluateBonds(this.population[bestIndex]);
         int overlaps = this.evaluator.evaluateOverlaps(this.population[bestIndex]);
 
-        this.pdraw.setFilename(String.format("gen_%07d.jpg",gen));
-        this.pdraw.drawProteinToFile(this.population[bestIndex].getVertexList(), bestFitness, bonds, overlaps, gen);
+        this.visualizer.setFilename(String.format("gen_%07d.jpg",gen));
+        this.visualizer.drawProtein(this.population[bestIndex].getVertexList(), bestFitness, bonds, overlaps, gen);
 
         System.out.println("The fitness is: " + bestFitness
                     + " [hydrophobicBonds = " + bonds + " | overlaps = " + overlaps + "]");
@@ -134,4 +133,12 @@ public class GeneticAlgorithm {
 
         return bestIndex;
     }
+
+    public int getMaxH() {
+        return this.visualizer.getMaxH();
+    }
+
+    public int getMaxW() {
+        return  this.visualizer.getMaxH();
+    }
 }
diff --git a/src/main/java/MainClasses/Main.java b/src/main/java/MainClasses/Main.java
index 76b68ab4dfa0ce6fa53c7e8d904486c6948d90c7..8d21429f453ef2fd437bcb6fec336a0b7f029750 100644
--- a/src/main/java/MainClasses/Main.java
+++ b/src/main/java/MainClasses/Main.java
@@ -15,8 +15,9 @@ public class Main {
         GeneticAlgorithm ga = new GeneticAlgorithm(protein);
         ga.simulateGenerations();
 
+//        if (Config.isVidoable && Config.doVideo)
         try {
-            VideoCreator.createVideo(config.getProperties());
+            VideoCreator.createVideo(config.getProperties(), ga.getMaxH(), ga.getMaxW());
         } catch (IOException e) {
             e.printStackTrace();
         }
diff --git a/src/main/java/Visualization/Cell.java b/src/main/java/Visualization/Cell.java
new file mode 100644
index 0000000000000000000000000000000000000000..c801e7051ea5865bd9be72ac658db473c2d883ae
--- /dev/null
+++ b/src/main/java/Visualization/Cell.java
@@ -0,0 +1,48 @@
+package Visualization;
+
+import Enums.State;
+
+import java.util.ArrayList;
+
+public class Cell {
+    public ArrayList<State> states = new ArrayList<>();
+    public ArrayList<Integer> aminoIndexes = new ArrayList<>();
+
+    public Cell() {
+        states.add(State.Empty);
+    }
+
+    public void addState (State state) {
+        if (states.get(0).equals(State.Empty)) {
+            states.clear();
+        }
+        states.add(state);
+    }
+
+    public void addAminoIndex (int aminoIndex) {
+        aminoIndexes.add(aminoIndex);
+    }
+
+    public State getRelevantDrawState () {
+        State rc = states.get(0);
+        if (states.size() > 1) {
+            if (rc.equals(State.Hydrophobic)) {
+                for (State s : states) {
+                    if (s.equals(State.Hydrophilic)) {
+                        return State.Mixed;
+                    }
+                }
+                return State.HydrophobicMulti;
+
+            } else if (rc.equals(State.Hydrophilic)) {
+                for (State s : states) {
+                    if (s.equals(State.Hydrophobic)) {
+                        return State.Mixed;
+                    }
+                }
+                return State.HydrophilicMulti;
+            }
+        }
+        return rc;
+    }
+}
diff --git a/src/main/java/Visualization/ProteinDrawer.java b/src/main/java/Visualization/ProteinDrawer.java
deleted file mode 100644
index 4a95ee9fb2dd7bc825a3a15b1a313c44be897197..0000000000000000000000000000000000000000
--- a/src/main/java/Visualization/ProteinDrawer.java
+++ /dev/null
@@ -1,354 +0,0 @@
-package Visualization;
-
-import MainClasses.Vertex;
-
-import javax.imageio.ImageIO;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class ProteinDrawer {
-
-    String folder;
-    String filename;
-
-    // Used only for the console output
-    String consoleEmpty = "   ";
-    String consoleHydrophobic = "(o)";
-    String consoleHydrophilic = "(i)";
-    String consoleHydrophobicMulti = "{o}";
-    String consoleHydrophilicMulti = "{i}";
-    String consoleMixed = "{z}";
-    String consoleConnectionVertical = " | ";
-    String consoleConnectionHorizontal = "---";
-
-    // For image
-    int pixelsPerCell = 40;
-    int margin = pixelsPerCell * 2;
-    int outline = 2;
-    public static final Font font = new Font("Sans-Serif", Font.PLAIN, 15);
-    public static final Color imageBackground = new Color(255, 255, 255);
-    public static final Color imageConnection = new Color(0, 0, 0);
-    public static final Color imageOutline = new Color(0, 0, 0);
-    public static final Color imageHydrophobic = new Color(205, 0, 0);
-    public static final Color imageHydrophilic = new Color(0, 0, 255);
-    public static final Color imageMixed = new Color(205, 0, 205);
-    public static final Color imageAminoText = new Color(180, 180, 180);
-    public static final Color imageText = new Color(0,0,0);
-
-    public static int maxHeight;
-    public static int maxWidth;
-
-    public ProteinDrawer(String folder) {
-        this.folder = folder;
-        this.filename = "image.jpg"; // Default
-
-        maxHeight = 0;
-        maxWidth = 0;
-    }
-
-    public void drawProteinToFile(ArrayList<Vertex> vertexListOriginal, double fit, int bond, int over, int gen) {
-        // Copy VertexList to be able to manipulate it
-        ArrayList<Vertex> vertexList = deepCopyVertexList(vertexListOriginal);
-
-        Cell[][] cellArray = convertProteinTo2DArray(vertexList);
-
-        int height = (cellArray.length * pixelsPerCell) + margin * 2;
-        int width = (cellArray[0].length * pixelsPerCell) + margin * 2;
-
-        if (height > maxHeight) {
-            maxHeight = height;
-        }
-        if (width > maxWidth) {
-            maxWidth = width;
-        }
-
-        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-        Graphics2D g2 = image.createGraphics();
-        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-        g2.setFont(font);
-        FontMetrics metrics = g2.getFontMetrics();
-        int ascent = metrics.getAscent();
-
-        // Background
-        g2.setColor(imageBackground);
-        g2.fillRect(0, 0, width, height);
-
-        for (int yIndex = cellArray.length-1; yIndex >= 0; yIndex--) {
-            int yIndexPosition = cellArray.length-1 - yIndex;
-
-            for (int xIndex = 0; xIndex < cellArray[0].length; xIndex++) {
-                Color aminoColor = null;
-
-                State cellState = cellArray[yIndex][xIndex].getRelevantDrawState();
-
-                switch (cellState) {
-                    case Empty:
-                        break;
-
-                    case Hydrophobic:
-                    case HydrophobicMulti:
-                        aminoColor = imageHydrophobic;
-                        break;
-
-                    case Hydrophilic:
-                    case HydrophilicMulti:
-                        aminoColor = imageHydrophilic;
-                        break;
-
-                    case Mixed:
-                        aminoColor = imageMixed;
-                        break;
-
-                    case ConnectionVertical:
-                        g2.setColor(imageConnection);
-                        g2.fillRect((xIndex * pixelsPerCell) + margin + (pixelsPerCell/2)-outline,
-                                (yIndexPosition * pixelsPerCell) + margin,
-                                outline * 2, pixelsPerCell);
-                        break;
-
-                    case ConnectionHorizontal:
-                        g2.setColor(imageConnection);
-                        g2.fillRect((xIndex * pixelsPerCell) + margin,
-                                (yIndexPosition * pixelsPerCell) + margin + (pixelsPerCell/2)-outline,
-                                pixelsPerCell, outline * 2);
-                        break;
-                }
-
-                if (aminoColor != null) {
-                    g2.setColor(imageOutline);
-                    g2.fillRect((xIndex * pixelsPerCell) + margin, (yIndexPosition * pixelsPerCell) + margin,
-                            pixelsPerCell, pixelsPerCell);
-                    g2.setColor(aminoColor);
-                    g2.fillRect((xIndex * pixelsPerCell) + outline + margin, (yIndexPosition * pixelsPerCell) + outline + margin,
-                            pixelsPerCell - (outline * 2), pixelsPerCell - (outline * 2));
-
-                    g2.setColor(imageAminoText);
-                    String label = "";
-                    for (int aminoIndex : cellArray[yIndex][xIndex].aminoIndexes) {
-                        label += aminoIndex + " ";
-                    }
-                    int labelWidth = metrics.stringWidth(label);
-                    int x = (xIndex * pixelsPerCell) + margin + (pixelsPerCell/2) - (labelWidth/2) + outline;
-                    int y = (yIndexPosition * pixelsPerCell) + margin + (pixelsPerCell/2) + (ascent/2) - outline;
-                    g2.drawString(label, x, y);
-                }
-            }
-        }
-
-        g2.setColor(imageText);
-        String label = "Gen: " + gen
-                + "     Fitness: " + String.format("%.4f", fit)
-                + "     H/H Bonds: " + bond
-                + "     Overlaps: " + over;
-        int labelWidth = metrics.stringWidth(label);
-        int x = margin / 4;
-        int y = margin / 4;
-        g2.drawString(label, x, y);
-
-        if (!new File(folder).exists()) new File(folder).mkdirs();
-
-        try {
-            ImageIO.write(image, "jpg", new File(folder + File.separator + filename));
-        } catch (IOException e) {
-            e.printStackTrace();
-            System.exit(0);
-        }
-    }
-
-    public void printProtein(ArrayList<Vertex> vertexListOriginal) {
-        // Copy VertexList to be able to manipulate it
-        ArrayList<Vertex> vertexList = deepCopyVertexList(vertexListOriginal);
-
-        Cell[][] cellArray = convertProteinTo2DArray(vertexList);
-
-        for (int yIndex = cellArray.length-1; yIndex >= 0; yIndex--) {
-            for (int xIndex = 0; xIndex < cellArray[0].length; xIndex++) {
-                System.out.print(convertCellToString(cellArray[yIndex][xIndex]));
-            }
-            System.out.println();
-        }
-        System.out.println();
-    }
-
-    private ArrayList<Vertex> deepCopyVertexList (List<Vertex> vertexListOriginal) {
-        ArrayList<Vertex> vertexList = new ArrayList<>();
-        for (Vertex v : vertexListOriginal) {
-            Vertex vNew = new Vertex(v.x, v.y, v.isHydrophobic, v.outgoingDirection);
-            vertexList.add(vNew);
-        }
-        return vertexList;
-    }
-
-    private Cell[][] convertProteinTo2DArray(ArrayList<Vertex> vertexList) {
-        // Determine size
-        int minX = 0;
-        int maxX = 0;
-        int minY = 0;
-        int maxY = 0;
-        for (Vertex vertex : vertexList) {
-            if (vertex.x < minX) {
-                minX = vertex.x;
-            }
-            if (vertex.x > maxX) {
-                maxX = vertex.x;
-            }
-            if (vertex.y < minY) {
-                minY = vertex.y;
-            }
-            if (vertex.y > maxY) {
-                maxY = vertex.y;
-            }
-        }
-
-        // Fix min values to 0 and double vertex coordinates to make room for connections
-        maxX += Math.abs(minX);
-        maxY += Math.abs(minY);
-        for (Vertex vertex : vertexList) {
-            vertex.x += Math.abs(minX);
-            vertex.x *= 2;
-            vertex.y += Math.abs(minY);
-            vertex.y *= 2;
-        }
-
-        // Add vertexes and connections to 2d array
-        Cell[][] cellArray = new Cell[maxY * 2 + 1][maxX * 2 + 1];
-        for (int yIndex = 0; yIndex < maxY * 2 + 1; yIndex++) {
-            for (int xIndex = 0; xIndex < maxX * 2 + 1; xIndex++) {
-                cellArray[yIndex][xIndex] = new Cell();
-            }
-        }
-
-        for (int i = 0; i < vertexList.size(); i++) {
-            Vertex vertex = vertexList.get(i);
-            if (vertex.isHydrophobic) {
-                cellArray[vertex.y][vertex.x].addState(State.Hydrophobic);
-            } else {
-                cellArray[vertex.y][vertex.x].addState(State.Hydrophilic);
-            }
-            cellArray[vertex.y][vertex.x].addAminoIndex(i);
-
-            // Add connection, except on the last one
-            if (i + 1 != vertexList.size()) {
-                if (vertex.outgoingDirection == 0) {
-                    cellArray[vertex.y + 1][vertex.x].addState(State.ConnectionVertical);
-                } else if (vertex.outgoingDirection == 1) {
-                    cellArray[vertex.y][vertex.x + 1].addState(State.ConnectionHorizontal);
-                } else if (vertex.outgoingDirection == 2) {
-                    cellArray[vertex.y - 1][vertex.x].addState(State.ConnectionVertical);
-                } else if (vertex.outgoingDirection == 3) {
-                    cellArray[vertex.y][vertex.x - 1].addState(State.ConnectionHorizontal);
-                }
-            }
-        }
-
-        return cellArray;
-    }
-
-    private String convertCellToString(Cell cell) {
-
-        State cellState = cell.getRelevantDrawState ();
-
-        switch (cellState) {
-            case Empty:
-                return consoleEmpty;
-
-            case Hydrophobic:
-                    return consoleHydrophobic;
-
-            case Hydrophilic:
-                    return consoleHydrophilic;
-
-            case HydrophobicMulti:
-                return consoleHydrophobicMulti;
-
-            case HydrophilicMulti:
-                return consoleHydrophilicMulti;
-
-            case Mixed:
-                return consoleMixed;
-
-            case ConnectionVertical:
-                return consoleConnectionVertical;
-
-            case ConnectionHorizontal:
-                return consoleConnectionHorizontal;
-
-        }
-        // Fallback
-        return consoleEmpty;
-    }
-
-    public String getFolder() {
-        return folder;
-    }
-
-    public void setFolder(String folder) {
-        this.folder = folder;
-    }
-
-    public String getFilename() {
-        return filename;
-    }
-
-    public void setFilename(String filename) {
-        this.filename = filename;
-    }
-}
-
-class Cell {
-    ArrayList<State> states = new ArrayList<>();
-    ArrayList<Integer> aminoIndexes = new ArrayList<>();
-
-    public Cell() {
-        states.add(State.Empty);
-    }
-
-    public void addState (State state) {
-        if (states.get(0).equals(State.Empty)) {
-            states.clear();
-        }
-        states.add(state);
-    }
-
-    public void addAminoIndex (int aminoIndex) {
-        aminoIndexes.add(aminoIndex);
-    }
-
-    public State getRelevantDrawState () {
-        State rc = states.get(0);
-        if (states.size() > 1) {
-            if (rc.equals(State.Hydrophobic)) {
-                for (State s : states) {
-                    if (s.equals(State.Hydrophilic)) {
-                        return State.Mixed;
-                    }
-                }
-                return State.HydrophobicMulti;
-
-            } else if (rc.equals(State.Hydrophilic)) {
-                for (State s : states) {
-                    if (s.equals(State.Hydrophobic)) {
-                        return State.Mixed;
-                    }
-                }
-                return State.HydrophilicMulti;
-            }
-        }
-        return rc;
-    }
-}
-
-enum State {
-    Empty,
-    Hydrophobic,
-    Hydrophilic,
-    HydrophobicMulti,
-    HydrophilicMulti,
-    Mixed,
-    ConnectionVertical,
-    ConnectionHorizontal
-}
\ No newline at end of file
diff --git a/src/main/java/Visualization/VideoCreator.java b/src/main/java/Visualization/VideoCreator.java
index f3041c35b8927030fecdb9d337c9775630e12b8d..af4ddb9981a921c993308195eebe7b68e63eab75 100644
--- a/src/main/java/Visualization/VideoCreator.java
+++ b/src/main/java/Visualization/VideoCreator.java
@@ -1,5 +1,7 @@
 package Visualization;
 
+import MainClasses.Config;
+
 import java.awt.Graphics2D;
 import java.awt.image.BufferedImage;
 import java.io.File;
@@ -28,14 +30,14 @@ public class VideoCreator{
         }
     };
 
-    private static int[] resizeImages(String imagesPath) throws IOException {
+    private static int[] resizeImages(String imagesPath, int maxH, int maxW) throws IOException {
         dir = new File(imagesPath);
         int[] widthHeight = new int[2];
 
         if (dir.isDirectory()) {
             // reads input images and determines maximum required size
-            int maxHeight = ProteinDrawer.maxHeight;
-            int maxWidth = ProteinDrawer.maxWidth;
+            int maxHeight = maxH;
+            int maxWidth = maxW;
 
             if (maxHeight <= 0 || maxWidth <= 0) {
                 int counter = 1;
@@ -71,7 +73,7 @@ public class VideoCreator{
 
                 // draws input image to the top left corner
                 Graphics2D g2d = outputImage.createGraphics();
-                g2d.setColor(ProteinDrawer.imageBackground);
+                g2d.setColor(Config.imageBackground);
                 g2d.fillRect(0,0, maxWidth, maxHeight);
                 g2d.drawImage(inputImage, 0, 0, inputImage.getWidth(), inputImage.getHeight(), null);
                 g2d.dispose();
@@ -85,13 +87,13 @@ public class VideoCreator{
     }
 
     // MainClasses.Main function
-    public static void createVideo(Properties properties) throws IOException {
+    public static void createVideo(Properties properties, int maxH, int maxW) throws IOException {
         String imagesPath = properties.getProperty("imageSequencePath");
         String videoPathAndFile = properties.getProperty("videoPathAndFile");
         int imgInterval = Integer.parseInt(properties.getProperty("imgInterval"));
         dir = new File(imagesPath);
 
-        int[] widthHeight = VideoCreator.resizeImages(imagesPath);
+        int[] widthHeight = VideoCreator.resizeImages(imagesPath, maxH, maxW);
 
         File file = new File(videoPathAndFile);
         if (!file.exists()) {
diff --git a/src/main/java/Visualization/Visualizers/VisualizerNESWtoConsole.java b/src/main/java/Visualization/Visualizers/VisualizerNESWtoConsole.java
new file mode 100644
index 0000000000000000000000000000000000000000..22af4d1bcd05f8687644ed651c6443a795ba3616
--- /dev/null
+++ b/src/main/java/Visualization/Visualizers/VisualizerNESWtoConsole.java
@@ -0,0 +1,90 @@
+package Visualization.Visualizers;
+
+import Enums.State;
+import Interfaces.Visualizer;
+import MainClasses.Config;
+import MainClasses.Vertex;
+import Visualization.Cell;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class VisualizerNESWtoConsole implements Visualizer {
+
+    int maxHeight;
+    int maxWidth;
+
+    public VisualizerNESWtoConsole() {
+        this.maxHeight = 0;
+        this.maxWidth = 0;
+    }
+
+    public void drawProtein(ArrayList<Vertex> vertexListOriginal, double fit, int bond, int over, int gen) {
+        // Copy VertexList to be able to manipulate it
+        ArrayList<Vertex> vertexList = Visualizer.deepCopyVertexList(vertexListOriginal);
+
+        Cell[][] cellArray = Visualizer.convertProteinTo2DArray(vertexList);
+
+        for (int yIndex = cellArray.length-1; yIndex >= 0; yIndex--) {
+            for (int xIndex = 0; xIndex < cellArray[0].length; xIndex++) {
+                System.out.print(convertCellToString(cellArray[yIndex][xIndex]));
+            }
+            System.out.println();
+        }
+        System.out.println();
+    }
+
+    private String convertCellToString(Cell cell) {
+
+        State cellState = cell.getRelevantDrawState ();
+
+        switch (cellState) {
+            case Empty:
+                return Config.consoleEmpty;
+
+            case Hydrophobic:
+                return Config.consoleHydrophobic;
+
+            case Hydrophilic:
+                return Config.consoleHydrophilic;
+
+            case HydrophobicMulti:
+                return Config.consoleHydrophobicMulti;
+
+            case HydrophilicMulti:
+                return Config.consoleHydrophilicMulti;
+
+            case Mixed:
+                return Config.consoleMixed;
+
+            case ConnectionVertical:
+                return Config.consoleConnectionVertical;
+
+            case ConnectionHorizontal:
+                return Config.consoleConnectionHorizontal;
+
+        }
+        // Fallback
+        return Config.consoleEmpty;
+    }
+
+
+    @Override
+    public void setFilename(String format) {
+        // Only here so file based visualizers work
+    }
+
+    @Override
+    public int getMaxH() {
+        return this.maxHeight;
+    }
+
+    @Override
+    public int getMaxW() {
+        return  this.maxWidth;
+    }
+}
diff --git a/src/main/java/Visualization/Visualizers/VisualizerNESWtoFile.java b/src/main/java/Visualization/Visualizers/VisualizerNESWtoFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..0300a1a50edf19187b46cb5f8f04f9d3576a9727
--- /dev/null
+++ b/src/main/java/Visualization/Visualizers/VisualizerNESWtoFile.java
@@ -0,0 +1,160 @@
+package Visualization.Visualizers;
+
+import Enums.State;
+import Interfaces.Visualizer;
+import MainClasses.Config;
+import MainClasses.Vertex;
+import Visualization.Cell;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class VisualizerNESWtoFile implements Visualizer {
+
+    String folder;
+    String filename;
+
+    int maxHeight;
+    int maxWidth;
+
+    // For image sizing
+    int pixelsPerCell = 40;
+    int margin = pixelsPerCell * 2;
+    int outline = 2;
+
+    public VisualizerNESWtoFile(String folder) {
+        this.folder = folder;
+        this.filename = "image.jpg"; // Default
+
+        this.maxHeight = 0;
+        this.maxWidth = 0;
+    }
+
+    public void drawProtein(ArrayList<Vertex> vertexListOriginal, double fit, int bond, int over, int gen) {
+        // Copy VertexList to be able to manipulate it
+        ArrayList<Vertex> vertexList = Visualizer.deepCopyVertexList(vertexListOriginal);
+
+        Cell[][] cellArray = Visualizer.convertProteinTo2DArray(vertexList);
+
+        int height = (cellArray.length * pixelsPerCell) + margin * 2;
+        int width = (cellArray[0].length * pixelsPerCell) + margin * 2;
+
+        if (height > maxHeight) {
+            maxHeight = height;
+        }
+        if (width > maxWidth) {
+            maxWidth = width;
+        }
+
+        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g2 = image.createGraphics();
+        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+        g2.setFont(Config.font);
+        FontMetrics metrics = g2.getFontMetrics();
+        int ascent = metrics.getAscent();
+
+        // Background
+        g2.setColor(Config.imageBackground);
+        g2.fillRect(0, 0, width, height);
+
+        for (int yIndex = cellArray.length-1; yIndex >= 0; yIndex--) {
+            int yIndexPosition = cellArray.length-1 - yIndex;
+
+            for (int xIndex = 0; xIndex < cellArray[0].length; xIndex++) {
+                Color aminoColor = null;
+
+                State cellState = cellArray[yIndex][xIndex].getRelevantDrawState();
+
+                switch (cellState) {
+                    case Empty:
+                        break;
+
+                    case Hydrophobic:
+                    case HydrophobicMulti:
+                        aminoColor = Config.imageHydrophobic;
+                        break;
+
+                    case Hydrophilic:
+                    case HydrophilicMulti:
+                        aminoColor = Config.imageHydrophilic;
+                        break;
+
+                    case Mixed:
+                        aminoColor = Config.imageMixed;
+                        break;
+
+                    case ConnectionVertical:
+                        g2.setColor(Config.imageConnection);
+                        g2.fillRect((xIndex * pixelsPerCell) + margin + (pixelsPerCell/2)-outline,
+                                (yIndexPosition * pixelsPerCell) + margin,
+                                outline * 2, pixelsPerCell);
+                        break;
+
+                    case ConnectionHorizontal:
+                        g2.setColor(Config.imageConnection);
+                        g2.fillRect((xIndex * pixelsPerCell) + margin,
+                                (yIndexPosition * pixelsPerCell) + margin + (pixelsPerCell/2)-outline,
+                                pixelsPerCell, outline * 2);
+                        break;
+                }
+
+                if (aminoColor != null) {
+                    g2.setColor(Config.imageOutline);
+                    g2.fillRect((xIndex * pixelsPerCell) + margin, (yIndexPosition * pixelsPerCell) + margin,
+                            pixelsPerCell, pixelsPerCell);
+                    g2.setColor(aminoColor);
+                    g2.fillRect((xIndex * pixelsPerCell) + outline + margin, (yIndexPosition * pixelsPerCell) + outline + margin,
+                            pixelsPerCell - (outline * 2), pixelsPerCell - (outline * 2));
+
+                    g2.setColor(Config.imageAminoText);
+                    String label = "";
+                    for (int aminoIndex : cellArray[yIndex][xIndex].aminoIndexes) {
+                        label += aminoIndex + " ";
+                    }
+                    int labelWidth = metrics.stringWidth(label);
+                    int x = (xIndex * pixelsPerCell) + margin + (pixelsPerCell/2) - (labelWidth/2) + outline;
+                    int y = (yIndexPosition * pixelsPerCell) + margin + (pixelsPerCell/2) + (ascent/2) - outline;
+                    g2.drawString(label, x, y);
+                }
+            }
+        }
+
+        g2.setColor(Config.imageText);
+        String label = "Gen: " + gen
+                + "     Fitness: " + String.format("%.4f", fit)
+                + "     H/H Bonds: " + bond
+                + "     Overlaps: " + over;
+        int labelWidth = metrics.stringWidth(label);
+        int x = margin / 4;
+        int y = margin / 4;
+        g2.drawString(label, x, y);
+
+        if (!new File(folder).exists()) new File(folder).mkdirs();
+
+        try {
+            ImageIO.write(image, "jpg", new File(folder + File.separator + filename));
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.exit(0);
+        }
+    }
+
+    @Override
+    public void setFilename(String filename) {
+        this.filename = filename;
+    }
+
+    @Override
+    public int getMaxH() {
+        return this.maxHeight;
+    }
+
+    @Override
+    public int getMaxW() {
+        return  this.maxWidth;
+    }
+}