Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to serialize an object of android.graphics.Path

I'm trying to store objects of Android.graphics.Path in internal device memory. Does anyone know how to serialize a android.graphics.Path object? And also, is there any other way of storing a Path object? Thanks.

like image 753
sunchips Avatar asked Feb 07 '11 09:02

sunchips


People also ask

How do you serialize an image?

You can't serialize an Image . It is typically "hooked into" the sender's graphics environment in ways that serialization is not able to deal with. What you need to do is to mark the img field as transient . The net effect will be that the receiver sees null as the value.

What is serializable object in Android?

To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java. io. Serializable interface or its subinterface, java.

What does serializing an object do?

Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed.


2 Answers

The way I did it is to identify the methods that I needed from the original Path class and then simply override those methods as follows:

public class CustomPath extends Path implements Serializable {

private static final long serialVersionUID = -5974912367682897467L;

private ArrayList<PathAction> actions = new ArrayList<CustomPath.PathAction>();

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
    in.defaultReadObject();
    drawThisPath();
}

@Override
public void moveTo(float x, float y) {
    actions.add(new ActionMove(x, y));
    super.moveTo(x, y);
}

@Override
public void lineTo(float x, float y){
    actions.add(new ActionLine(x, y));
    super.lineTo(x, y);
}

private void drawThisPath(){
    for(PathAction p : actions){
        if(p.getType().equals(PathActionType.MOVE_TO)){
            super.moveTo(p.getX(), p.getY());
        } else if(p.getType().equals(PathActionType.LINE_TO)){
            super.lineTo(p.getX(), p.getY());
        }
    }
}

public interface PathAction {
    public enum PathActionType {LINE_TO,MOVE_TO};
    public PathActionType getType();
    public float getX();
    public float getY();
}

public class ActionMove implements PathAction, Serializable{
    private static final long serialVersionUID = -7198142191254133295L;

    private float x,y;

    public ActionMove(float x, float y){
        this.x = x;
        this.y = y;
    }

    @Override
    public PathActionType getType() {
        return PathActionType.MOVE_TO;
    }

    @Override
    public float getX() {
        return x;
    }

    @Override
    public float getY() {
        return y;
    }

}

public class ActionLine implements PathAction, Serializable{
    private static final long serialVersionUID = 8307137961494172589L;

    private float x,y;

    public ActionLine(float x, float y){
        this.x = x;
        this.y = y;
    }

    @Override
    public PathActionType getType() {
        return PathActionType.LINE_TO;
    }

    @Override
    public float getX() {
        return x;
    }

    @Override
    public float getY() {
        return y;
    }

}
}

In my example I need "moveTo" and "lineTo", so in this case I simply hold the drawing information in a list. This list contains the drawing information (what I call "action") needed by Path in order to restore the drawing as it looked like before the object was serialized. Then when I deserialize my objects of type CustomPath i make sure to let the default serialization protocol call "drawThisPath", so the path is redrawn.

like image 75
Rabie Jradi Avatar answered Sep 28 '22 05:09

Rabie Jradi


I've just managed to solve this. My application is based off the FingerPaintDemo, so makes use of just moveTo and quadTo, but I think you can apply this approach to any Path functions.

First, extend Path as follows:

import android.graphics.Path;

import java.util.ArrayList;

import java.io.Serializable;

public class SerializablePath extends Path implements Serializable {

    private ArrayList<float[]> pathPoints;

    public SerializablePath() {
        super();
        pathPoints = new ArrayList<float[]>();
    }

    public SerializablePath(SerializablePath p) {
        super(p);
        pathPoints = p.pathPoints;
    }

    public void addPathPoints(float[] points) {
        this.pathPoints.add(points);
    }

    public void loadPathPointsAsQuadTo() {
        float[] initPoints = pathPoints.remove(0);
        this.moveTo(initPoints[0], initPoints[1]);
        for (float[] pointSet : pathPoints) {
            this.quadTo(pointSet[0], pointSet[1], pointSet[2], pointSet[3]);
        } 
    }
}

I don't think I need to paste the implementation code, but if you want to see it let me know. Basically just as you call something like myPath.quadTo(x1, y1, x2, y2), also call myPath.addPathPoints(new float[]{x1, y1, x2, y2}).

Serialize the object to disk as normal, and when you read it back in, just be sure to call myPath.loadPathPointsAsQuadTo().

like image 42
brk3 Avatar answered Sep 28 '22 03:09

brk3