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

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

问题描述

我已经开始工作的我的第一个Android应用程序,并有一个处理带有多个图层的图像的应用的基础。我能够出口一台版本的项目文件为PNG,但我希望能够保存进行后​​期编辑(包括适用于某些层的任何选项,如基于文本层)的分层图像。

不管怎样,我已确保需要被写入到文件中的类是可序列化,但遇到了一个位所造成的事实,android.graphics.Bitmap不是可序列化道路块。下面code基本输出位图作为一个PNG至ByteArray,应该读回作为的readObject的一部分。然而,当code同时运行 - 我可以验证所读取的'imageByteArrayLength'变量是相同被输出 - 但'位图图象总是空

任何帮助将是很大的AP preciated。感谢您的阅读。

 私人字符串名称;
私人诠释宽度;
私人诠释高度;
私人位图sourceImage;
私人帆布sourceCanvas;
私人位图currentImage;
私人帆布currentCanvas;
私人油漆currentPaint;

私人无效的writeObject(ObjectOutputStream的了)抛出IOException异常{
    out.writeObject(职称);
    out.writeInt(宽);
    out.writeInt(高度);

    ByteArrayOutputStream流=新ByteArrayOutputStream();
    currentImage.com preSS(Bitmap.Com pressFormat.PNG,100,流);
    byte []的imageByteArray = stream.toByteArray();

    INT长度= imageByteArray.length;
    out.writeInt(长);
    out.write(imageByteArray);
}

私人无效的readObject(ObjectInputStream中的)抛出IOException异常,ClassNotFoundException异常{
    this.title =(字符串)in.readObject();
    this.width = in.readInt();
    this.height = in.readInt();

    INT imageByteArrayLength = in.readInt();
    byte []的imageByteArray =新的字节[imageByteArrayLength]
    in.read(imageByteArray,0,imageByteArrayLength);

    BitmapFactory.Options选择=新BitmapFactory.Options();
    opt.in preferredConfig = Bitmap.Config.ARGB_8888;

    位图图像= BitmapFactory.de codeByteArray(imageByteArray,0,imageByteArrayLength,OPT);

    sourceImage = Bitmap.createBitmap(宽度,高度,Bitmap.Config.ARGB_8888);
    currentImage = Bitmap.createBitmap(宽度,高度,Bitmap.Config.ARGB_8888);

    sourceCanvas =新的Canvas(sourceImage);
    currentCanvas =新的Canvas(currentImage);
    currentPaint =新的油漆(Paint.ANTI_ALIAS_FLAG);

    如果(图像!= NULL){
        sourceCanvas.drawBitmap(图像,0,0,currentPaint);
    }
}
 

解决方案

过了一段时间,但我已经找到了干净的解决这个问题。我公司生产的自定义对象(BitmapDataObject)即实现Serializable接口,并有一个byte []从原来的位图存储PNG数据。用这种方法,数据被正确地存储在用ObjectOutputStream / ObjectInputStream的 - 这有效地允许一个序列化,并通过存储它作为在自定义对象一个字节[]一个PNG反序列化Bitmap对象。下面的code解析我的查询。

 私人字符串名称;
私人诠释sourceWidth,currentWidth;
私人诠释sourceHeight,currentHeight;
私人位图sourceImage;
私人帆布sourceCanvas;
私人位图currentImage;
私人帆布currentCanvas;
私人油漆currentPaint;

保护类BitmapDataObject实现Serializable {
    私有静态最后长的serialVersionUID = 111696345129311948L;
    公共字节[] imageByteArray;
}

/ **包含了序列化 - 写这层到输出流。 * /
私人无效的writeObject(ObjectOutputStream的了)抛出IOException异常{
    out.writeObject(职称);
    out.writeInt(currentWidth);
    out.writeInt(currentHeight);

    ByteArrayOutputStream流=新ByteArrayOutputStream();
    currentImage.com preSS(Bitmap.Com pressFormat.PNG,100,流);
    BitmapDataObject bitmapDataObject =新BitmapDataObject();
    bitmapDataObject.imageByteArray = stream.toByteArray();

    out.writeObject(bitmapDataObject);
}

/ **包含了序列化 - 读取所提供的输入流这个对象。 * /
私人无效的readObject(ObjectInputStream中的)抛出IOException异常,ClassNotFoundException异常{
    标题=(字符串)in.readObject();
    sourceWidth = currentWidth = in.readInt();
    sourceHeight = currentHeight = in.readInt();

    BitmapDataObject bitmapDataObject =(BitmapDataObject)in.readObject();
    位图图像= BitmapFactory.de codeByteArray(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 =新的Canvas(sourceImage);
    currentCanvas =新的Canvas(currentImage);

    currentPaint =新的油漆(Paint.ANTI_ALIAS_FLAG);
    thumbnailPaint =新的油漆(Paint.ANTI_ALIAS_FLAG);
    thumbnailPaint.setARGB(255,200,200,200);
    thumbnailPaint.setStyle(Paint.Style.FILL);
}
 

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).

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

解决方案

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天全站免登陆