在 Java 中序列化和反序列化 android.graphics.Bitmap [英] Serializing and De-Serializing android.graphics.Bitmap in Java

查看:32
本文介绍了在 Java 中序列化和反序列化 android.graphics.Bitmap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始开发我的第一个 android 应用程序,并拥有处理具有多层图像的应用程序的基础.我可以将项目文件的平面版本导出为 PNG,但我希望能够保存分层图像以供以后编辑(包括应用于某些图层的任何选项,例如基于文本的图层).

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 the project file as a PNG but I would like to be able to save the layered image for later editing (including any options applied to certain layers, such as text based layers).

无论如何,我已确保需要写入文件的类是可序列化的",但由于 android.graphics.Bitmap 不可序列化,因此遇到了一些障碍.以下代码基本上将位图作为 PNG 输出到 ByteArray 中,并且应该将其作为readObject"的一部分读回.但是,当代码运行时——我可以验证读入的imageByteArrayLength"变量与输出的变量相同——但位图图像"始终为空.

Anyway, I have ensured that the classes that need to be written to a file are 'Serializable' but have run into a bit of a road block caused by the fact that android.graphics.Bitmap isn't serializable. The following code essentially outputs the Bitmap as a PNG into a ByteArray and should read it back in as part of 'readObject'. However, when the code runs - I can verify that the 'imageByteArrayLength' variable that is read in is the same as that which is output - but the 'Bitmap image' is always null.

任何帮助将不胜感激.感谢阅读.

Any help would be greatly appreciated. Thanks for reading.

private String title;
private int width;
private int height;
private Bitmap sourceImage;
private Canvas sourceCanvas;        
private Bitmap currentImage;
private Canvas currentCanvas;   
private Paint currentPaint; 

private void writeObject(ObjectOutputStream out) throws IOException{
    out.writeObject(title);
    out.writeInt(width);
    out.writeInt(height);

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    currentImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] imageByteArray = stream.toByteArray();

    int length = imageByteArray.length;
    out.writeInt(length);
    out.write(imageByteArray);          
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
    this.title = (String)in.readObject();
    this.width = in.readInt();
    this.height = in.readInt();

    int imageByteArrayLength = in.readInt();
    byte[] imageByteArray = new byte[imageByteArrayLength];
    in.read(imageByteArray, 0, imageByteArrayLength);

    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inPreferredConfig = Bitmap.Config.ARGB_8888;

    Bitmap image = BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArrayLength, opt);

    sourceImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    currentImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

    sourceCanvas = new Canvas(sourceImage);
    currentCanvas = new Canvas(currentImage);
    currentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    if ( image != null ) {
        sourceCanvas.drawBitmap(image, 0, 0, currentPaint);
    }
}   

推荐答案

花了一段时间,但我已经找到了解决这个问题的简洁方法.我生成了一个自定义对象 (BitmapDataObject),它实现了 Serializable 并有一个 byte[] 来存储来自原始位图的 PNG 数据.使用它,数据正确存储在 ObjectOutputStream/ObjectInputStream 中 - 这有效地允许通过将 Bitmap 对象作为 PNG 存储在自定义对象的 byte[] 中来序列化和反序列化它.下面的代码解决了我的查询.

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);
}

这篇关于在 Java 中序列化和反序列化 android.graphics.Bitmap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆