Serializing and De-Serializing android.graphics.Bitmap in Java

后端 未结 3 662
后悔当初
后悔当初 2020-11-28 13:55

I have started work on an my first android application and have the basis of an application that handles an image with multiple layers. I am able to export a flat version of

相关标签:
3条回答
  • 2020-11-28 14:27

    Here is an example of a serializable object that can wrap bitmaps.

    public class BitmapDataObject implements Serializable {
    
        private Bitmap currentImage;
    
        public BitmapDataObject(Bitmap bitmap)
        {
            currentImage = bitmap;
        }
    
        private void writeObject(java.io.ObjectOutputStream out) throws IOException {
    
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            currentImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
    
            byte[] byteArray = stream.toByteArray();
    
            out.writeInt(byteArray.length);
            out.write(byteArray);
    
        }
    
        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
    
    
            int bufferLength = in.readInt();
    
            byte[] byteArray = new byte[bufferLength];
    
            int pos = 0;
            do {
                int read = in.read(byteArray, pos, bufferLength - pos);
    
                if (read != -1) {
                    pos += read;
                } else {
                    break;
                }
    
            } while (pos < bufferLength);
    
            currentImage = BitmapFactory.decodeByteArray(byteArray, 0, bufferLength);
    
        }
    }
    
    0 讨论(0)
  • 2020-11-28 14:28

    It took a while, but I have found a clean solution to this problem. I produced a custom object (BitmapDataObject) that implements Serializable and has a byte[] to store the PNG data from the original Bitmap. Using this, the data is stored correctly in the ObjectOutputStream / ObjectInputStream - which effectively allows one to Serialize and Deserialize a Bitmap object by storing it as a PNG in a byte[] in a custom object. The code below resolves my query.

    private String title;
    private int sourceWidth, currentWidth;
    private int sourceHeight, currentHeight;
    private Bitmap sourceImage;
    private Canvas sourceCanvas;        
    private Bitmap currentImage;
    private Canvas currentCanvas;   
    private Paint currentPaint; 
    
    protected class BitmapDataObject implements Serializable {
        private static final long serialVersionUID = 111696345129311948L;
        public byte[] imageByteArray;
    }
    
    /** Included for serialization - write this layer to the output stream. */
    private void writeObject(ObjectOutputStream out) throws IOException{
        out.writeObject(title);
        out.writeInt(currentWidth);
        out.writeInt(currentHeight);
    
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        currentImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
        BitmapDataObject bitmapDataObject = new BitmapDataObject();     
        bitmapDataObject.imageByteArray = stream.toByteArray();
    
        out.writeObject(bitmapDataObject);
    }
    
    /** Included for serialization - read this object from the supplied input stream. */
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
        title = (String)in.readObject();
        sourceWidth = currentWidth = in.readInt();
        sourceHeight = currentHeight = in.readInt();
    
        BitmapDataObject bitmapDataObject = (BitmapDataObject)in.readObject();
        Bitmap image = BitmapFactory.decodeByteArray(bitmapDataObject.imageByteArray, 0, bitmapDataObject.imageByteArray.length);
    
        sourceImage = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);
        currentImage = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);
    
        sourceCanvas = new Canvas(sourceImage);
        currentCanvas = new Canvas(currentImage);
    
        currentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        thumbnailPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        thumbnailPaint.setARGB(255, 200, 200, 200);
        thumbnailPaint.setStyle(Paint.Style.FILL);
    }
    
    0 讨论(0)
  • 2020-11-28 14:35

    Simply use this code for making a class BitmapDataObject. Use getters and setters to switch between Bitmap and BitmapDataObject classes.

    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.Serializable;
    
    public class BitmapDataObject implements Serializable {
    
        private Bitmap currentImage;
    
        public Bitmap getCurrentImage() {
            return currentImage;
        }
    
        public void setCurrentImage(Bitmap currentImage) {
            this.currentImage = currentImage;
        }
    
        public BitmapDataObject(Bitmap bitmap)
        {
            currentImage = bitmap;
        }
    
        private void writeObject(java.io.ObjectOutputStream out) throws IOException {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            currentImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();
            out.writeInt(byteArray.length);
            out.write(byteArray);
        }
    
        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
            int bufferLength = in.readInt();
            byte[] byteArray = new byte[bufferLength];
            int pos = 0;
            do {
                int read = in.read(byteArray, pos, bufferLength - pos);
    
                if (read != -1) {
                    pos += read;
                } else {
                    break;
                }
            } while (pos < bufferLength);
            currentImage = BitmapFactory.decodeByteArray(byteArray, 0, bufferLength);
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题