title: Scrolling Image using PixelWriter / Reader
body: <p>I'm trying to create a scrolling image that wraps around a canvas to follow its own tail. I've been trying to use PixelWriters and Readers to save off the vertical pixel lines that are scrolling off the screen to the West, and append these to a new image which, should grow on the RHS (East) of the screen.</p>
  
  <p>It scrolls, but that's all that's happening. I don't understand how to calculate the scanlines, so apologies for this part.</p>
  
  <p>Any help appreciated.</p>
  
  <pre><code>package controller;
  
  import javafx.animation.AnimationTimer;
  import javafx.scene.canvas.Canvas;
  import javafx.scene.canvas.GraphicsContext;
  import javafx.scene.image.*;
  import javafx.scene.layout.*;
  import util.GraphicsUtils;
  
  import java.io.File;
  import java.nio.ByteBuffer;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  
  class ImageContainer extends HBox {
  int w, h;
  int translatedAmount = 0;
  Image image;
  Canvas canvas;
  long startNanoTime = System.nanoTime();
  WritableImage eastImage = null;
  
  public ImageContainer() {
      setVisible(true);
      load();
      w = (int) image.getWidth();
      h = (int) image.getHeight();
      canvas = new Canvas(w, h);
      int edgeX = (int) canvas.getWidth(); //You can set this a little west for visibility sake...whilst debugging
      getChildren().addAll(canvas);
      GraphicsContext gc = canvas.getGraphicsContext2D();
      canvas.setVisible(true);
      gc.drawImage(image, 0, 0, w, h);
      setPrefSize(w, h);
      eastImage = new WritableImage(translatedAmount+1, h); //create a new eastImage
  
      new AnimationTimer() {
          public void handle(long currentNanoTime) {
              if (((System.nanoTime() - startNanoTime) / 1000000000.0) &lt; 0.05) {
                  return;
              } else {
                  startNanoTime = System.nanoTime();
              }
  
              translatedAmount++;
  
              Image westLine = getSubImageRectangle(image, 1, 0, 1, h); //get a 1 pixel strip from west of main image
              PixelReader westLinepixelReader = westLine.getPixelReader(); //create a pixel reader for this image
              byte[] westLinePixelBuffer = new byte[1 * h * 4]; //create a buffer to store the pixels collected from the about to vanish westLine
              westLinepixelReader.getPixels(0, 0, 1, h, PixelFormat.getByteBgraInstance(), westLinePixelBuffer, 0, 4); //collect the pixels from westLine strip
  
              Image tempImg = eastImage; //save away the current east side image
  
              byte[] tempBuffer = new byte[(int)tempImg.getWidth() * h * 4];
              PixelReader tempImagePixelReader = tempImg.getPixelReader(); //create a pixel reader for our temp copy of the east side image
              tempImagePixelReader.getPixels(0, 0, (int)tempImg.getWidth(), h, PixelFormat.getByteBgraInstance(), tempBuffer, 0, 4); //save the tempImage into the tempBuffer
  
              eastImage = new WritableImage(translatedAmount+1, h); //create a new eastImage, but one size larger
              PixelWriter eastImagePixelWriter = eastImage.getPixelWriter(); //create a pixel writer for this new east side image
              eastImagePixelWriter.setPixels(1, 0, (int)tempImg.getWidth(), h, PixelFormat.getByteBgraInstance(), tempBuffer, 0, 4); //copy the temp image in at x=1
              eastImagePixelWriter.setPixels((int)tempImg.getWidth(), 0, 1, h, PixelFormat.getByteBgraInstance(), westLinePixelBuffer, 0, 4); //copy the westLine at x=tempImg.width
  
              image = getSubImageRectangle(image, 1, 0, (int) image.getWidth() - 1, h);
              gc.drawImage(image, 0, 0); //draw main image
              System.out.println(edgeX-eastImage.getWidth());
              gc.drawImage(eastImage, edgeX-eastImage.getWidth(), 0); //add lost image lines
          }
      }.start();
  }
  
  public void load() {
      Path imagePath = Paths.get("./src/main/resources/ribbonImages/clouds.png");
      File f = imagePath.toFile();
      assert f.exists();
      image = new Image(f.toURI().toString());
  }
  
  public Image getSubImageRectangle(Image image, int x, int y, int w, int h) {
      PixelReader pixelReader = image.getPixelReader();
      WritableImage newImage = new WritableImage(pixelReader, x, y, w, h);
      ImageView imageView = new ImageView();
      imageView.setImage(newImage);
      return newImage;
  }
  }
  </code></pre>