我已经开始研究我的第一个Android应用程序,并且具有处理具有多个图层的图像的应用程序的基础。我可以将项目文件的平面版本导出为PNG,但我希望能够保存分层图像以供以后编辑(包括应用于某些图层的任何选项,例如基于文本的图层)。
无论如何,我已经确保需要写入文件的类是'Serializable'但是由于android.graphics.Bitmap不可序列化而导致了一些障碍。下面的代码实际上将Bitmap作为PNG输出到ByteArray中,并应作为'readObject'的一部分将其读回。但是,当代码运行时 - 我可以验证读入的'imageByteArrayLength'变量与输出的变量相同 - 但'Bitmap image'始终为null。
非常感谢任何帮助。谢谢你的阅读。
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);
}
}
答案 0 :(得分:25)
花了一段时间,但我找到了解决这个问题的干净方法。我生成了一个实现Serializable的自定义对象(BitmapDataObject),并有一个byte []来存储来自原始Bitmap的PNG数据。使用它,数据正确存储在ObjectOutputStream / ObjectInputStream中 - 这有效地允许通过将Bitmap对象存储为自定义对象的byte []中的PNG来对其进行序列化和反序列化。下面的代码解决了我的问题。
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);
}
答案 1 :(得分:2)
以下是可以包装位图的可序列化对象的示例。
io.connect('http://my-weird-heroku-generated-url.com')
答案 2 :(得分:0)
只需使用此代码即可创建类BitmapDataObject。使用getter和setter在Bitmap和BitmapDataObject类之间切换。
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);
}
}