ArrayList_Serializable Demo Fails

  • Although it’s commendable, it isn’t required at all! :smirk:
  • We can still keep the class inside a “.pde” file by simply declaring it as static. :bulb:
  • Doing so we decouple the nested class from the sketch’s PApplet subclass. :broken_heart:
  • As a clear example, take a look at this old post about Serializable: :eyeglasses:

BtW, I’ve updated that previous old example to use a working Wikipedia image URL now: :link:


“Serializable_PImage.pde”:

/**
 * Serializable PImage (v1.1.3)
 * GoToLoop (2019/Dec/26)
 *
 * https://Discourse.Processing.org/t/arraylist-serializable-demo-fails/42770/3
 *
 * https://Discourse.Processing.org/t/
 * deserializing-objects-sent-from-a-client-program-to-a-server-program/16124/8
 */

static final String
  SERIALFILE = "imagen.serial", 

  FILENAME = "Wikipedia-logo-v2.png", 

  URL = "https://" + "www.Wikipedia.org/" +
  "portal/wikipedia.org/assets/img/" + FILENAME;

PImage img;

void settings() {
  img = loadAndSaveRemoteImage(URL);
  if (img == null) img = createImage(100, 100, RGB);

  size(img.width, img.height);
  noLoop();
}

void setup() {
  saveSerial(SERIALFILE, new SerializableImage(img));

  final SerializableImage sImg = (SerializableImage) loadSerial(SERIALFILE);
  println(sImg, sImg == sImg.clone());
  
  img = sImg.recreateImage();
}

void draw() {
  background(img);
}

“Functions.pde”:

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectOutput;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.ObjectInput;

PImage loadAndSaveRemoteImage(final String url) {
  final File f = dataFile(new File(url).getName());
  final String path = f.getPath();
  final PImage img = loadImage(f.isFile() ? path : url);

  println(url + ENTER + path);
  if (img != null) img.save(path);

  return img;
}

void saveSerial(final String filename, final Object o) {
  final File f = dataFile(filename);
  createPath(f);

  try {
    final ObjectOutput out = new ObjectOutputStream(new FileOutputStream(f));
    out.writeObject(o);
    out.close();
  }

  catch (final IOException e) {
    e.printStackTrace();
  }
}

Object loadSerial(final String filename) {
  final File f = dataFile(filename);
  println(f);

  try {
    final ObjectInput in = new ObjectInputStream(new FileInputStream(f));
    final Object o = in.readObject();
    in.close();
    return o;
  }

  catch (final IOException e) {
    e.printStackTrace();
  }

  catch (final ClassNotFoundException e) {
    e.printStackTrace();
  }

  return null;
}

“SerialClass.pde”:

import java.io.Serializable;

static public class SerializableImage implements Cloneable, Serializable {
  static protected final long serialVersionUID = 1_620_140_667;

  public int w, h, type, scale, pix[];

  public SerializableImage(final PImage img) {
    w = img.width;
    h = img.height;

    type = img.format;
    scale = img.pixelDensity;

    img.loadPixels();
    pix = img.pixels.clone();
  }

  public PImage recreateImage() {
    return recreateImage(null);
  }

  public PImage recreateImage(final PApplet p) {
    final PImage img = new PImage(w, h, type, scale);
    img.parent = p;

    img.loadPixels();
    PApplet.arrayCopy(pix, img.pixels);
    img.updatePixels();

    return img;
  }

  @Override public SerializableImage clone() {
    try {
      final SerializableImage sImg = (SerializableImage) super.clone();
      sImg.pix = sImg.pix.clone();
      return sImg;
    }

    catch (final CloneNotSupportedException e) {
      throw new RuntimeException(e);
    }
  }

  @Override public String toString() {
    return "[ " + w + " x " + h + " ]: " + w * h;
  }
}

Or if you still prefer a separate tab file “.java” approach: :coffee:

“SerializableImage.java”:

package processing.core;

public class SerializableImage implements Cloneable, java.io.Serializable {
  static protected final long serialVersionUID = 1_620_140_667;

  public int w, h, type, scale, pix[];

  public SerializableImage(final PImage img) {
    w = img.width;
    h = img.height;

    type = img.format;
    scale = img.pixelDensity;

    img.loadPixels();
    pix = img.pixels.clone();
  }

  public PImage recreateImage() {
    return recreateImage(null);
  }

  public PImage recreateImage(final PApplet p) {
    final PImage img = new PImage(w, h, type, scale);
    img.parent = p;

    img.loadPixels();
    PApplet.arrayCopy(pix, img.pixels);
    img.updatePixels();

    return img;
  }

  @Override public SerializableImage clone() {
    try {
      final SerializableImage sImg = (SerializableImage) super.clone();
      sImg.pix = sImg.pix.clone();
      return sImg;
    }

    catch (final CloneNotSupportedException e) {
      throw new RuntimeException(e);
    }
  }

  @Override public String toString() {
    return "[ " + w + " x " + h + " ]: " + w * h;
  }
}
3 Likes