Android, как сохранить растровое изображение - глючный код - PullRequest
7 голосов
/ 02 сентября 2010

Я пытаюсь сериализовать класс, в котором у меня есть переменная растрового изображения.Вот код, который немного работает .... Мне нужна помощь, чтобы выяснить, что все еще не так .....

private Bitmap myVideoScreenshotBm;

private void writeObject(ObjectOutputStream out) throws IOException{

    out.writeInt(myVideoScreenshotBm.getRowBytes());
    out.writeInt(myVideoScreenshotBm.getHeight());
    out.writeInt(myVideoScreenshotBm.getWidth());

    int bmSize = myVideoScreenshotBm.getHeight() * myVideoScreenshotBm.getRowBytes();
    ByteBuffer dst= ByteBuffer.allocate(bmSize);

    myVideoScreenshotBm.copyPixelsToBuffer(dst);

    byte[] bytesar=new byte[bmSize];
    dst.position(0);
    dst.get(bytesar);

    out.write(bytesar);


}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{

    int nbRowBytes=in.readInt();
    int height=in.readInt();
    int width=in.readInt();
    //
    int bmSize = nbRowBytes * height;
    byte[] toread= new byte[bmSize];

    in.read(toread, 0, toread.length);
    ByteBuffer dst= ByteBuffer.allocate(bmSize);
    dst.put(toread);
    dst.position(0);
    myVideoScreenshotBm=Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
    myVideoScreenshotBm.copyPixelsFromBuffer(dst);

}

Я не получаю ошибку, но растровое изображение, которое я получаю, неверно... также я не знаю, как узнать, какой флаг Bitmap.Config подходит ... как узнать?

любая помощь?

Ответы [ 3 ]

13 голосов
/ 08 сентября 2010

Вот код для сериализации с оптимизацией памяти.Я использую статический буфер, который увеличивается до самого большого размера растрового изображения и который я использую каждый раз.

public class Video implements Serializable{
public long videoId;
public String title;
public String publisher;
public String language;
public Date lastModified;
public Date published;
public String imageUrl;
public String url;
public Bitmap myVideoScreenshotBm;
public Date expireTime;
//public Drawable myVideoScreenshotDrawable;

private static ByteBuffer dst;
private static byte[] bytesar;

public Video (long newVideoId) {
    this.videoId=newVideoId;
}
private void writeObject(ObjectOutputStream out) throws IOException{

    out.writeLong(videoId);

    out.writeObject(title);
    out.writeObject(publisher);
    out.writeObject(language);
    out.writeObject(lastModified);
    out.writeObject(published);
    out.writeObject(expireTime);

    out.writeObject(imageUrl);
    out.writeObject(url);


    out.writeInt(myVideoScreenshotBm.getRowBytes());
    out.writeInt(myVideoScreenshotBm.getHeight());
    out.writeInt(myVideoScreenshotBm.getWidth());

    int bmSize = myVideoScreenshotBm.getRowBytes() * myVideoScreenshotBm.getHeight();
    if(dst==null || bmSize > dst.capacity())
        dst= ByteBuffer.allocate(bmSize);

    out.writeInt(dst.capacity());

    dst.position(0);

    myVideoScreenshotBm.copyPixelsToBuffer(dst);
    if(bytesar==null || bmSize > bytesar.length)
        bytesar=new byte[bmSize];

    dst.position(0);
    dst.get(bytesar);


    out.write(bytesar, 0, bytesar.length);

}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{

    videoId=in.readLong();

    title=(String) in.readObject();
    publisher=(String) in.readObject();
    language=(String) in.readObject();
    lastModified=(Date) in.readObject();
    published=(Date) in.readObject();
    expireTime=(Date) in.readObject();

    imageUrl = (String) in.readObject();
    url = (String) in.readObject();


    int nbRowBytes=in.readInt();
    int height=in.readInt();
    int width=in.readInt();

    int bmSize=in.readInt();



    if(bytesar==null || bmSize > bytesar.length)
        bytesar= new byte[bmSize];


    int offset=0;

    while(in.available()>0){
        offset=offset + in.read(bytesar, offset, in.available());
    }


    if(dst==null || bmSize > dst.capacity())
        dst= ByteBuffer.allocate(bmSize);
    dst.position(0);
    dst.put(bytesar);
    dst.position(0);
    myVideoScreenshotBm=Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
    myVideoScreenshotBm.copyPixelsFromBuffer(dst);
    //in.close();
}

}

4 голосов
/ 04 мая 2012

Для упрощения вы можете использовать стандартную сериализацию для всех полей, кроме растрового изображения.Просто пометьте растровое изображение как переходное и используйте out.defaultWriteObject ();и in.defaultReadObject () ;.Это действительно очищает код:

private String title;
private String description;
private transient Bitmap icon;

private synchronized void writeObject(final ObjectOutputStream out)
    throws IOException {
  // Serialize everything but the image
  out.defaultWriteObject();

  // Now serialize the image
  out.writeInt(icon.getRowBytes());
  out.writeInt(icon.getHeight());
  out.writeInt(icon.getWidth());
  out.writeInt(icon.getConfig().ordinal());

  final int bmSize = icon.getRowBytes() * icon.getHeight();
  if (dst == null || bmSize > dst.capacity()) {
    dst = ByteBuffer.allocate(bmSize);
  }
  dst.rewind();
  icon.copyPixelsToBuffer(dst);
  dst.flip();
  out.write(dst.array(), 0, bmSize);
}

private void readObject(ObjectInputStream in) throws IOException,
    ClassNotFoundException {
  // Read everything but the image
  in.defaultReadObject();

  // Now read the image
  final int nbRowBytes = in.readInt();
  final int height = in.readInt();
  final int width = in.readInt();
  final Bitmap.Config config = Bitmap.Config.values()[in.readInt()];

  final int bmSize = nbRowBytes * height;
  if (dst == null || bmSize > dst.capacity()) {
    dst = ByteBuffer.allocate(bmSize);
  }
  dst.rewind();
  in.read(dst.array(), 0, bmSize);

  icon = Bitmap.createBitmap(width, height, config);
  icon.copyPixelsFromBuffer(dst);
}
4 голосов
/ 04 июня 2011

Нет необходимости иметь избыточный массив + всю логику вокруг + использовать данные методы для работы с буфером + utf лучше для строк и избегать приведения + синхронизации (но в любом случае это не безопасно для потоков):

private synchronized void writeObject(final ObjectOutputStream out) throws IOException {
    out.writeUTF(title);
    out.writeUTF(url_friendly_name);
    out.writeUTF(creator_name);
    out.writeUTF(version);
    out.writeUTF(package_name);
    out.writeUTF(contact_website);
    out.writeInt(popularity);
    out.writeUTF(inconditional_redirect == null ? "" : inconditional_redirect);
    out.writeUTF(custom_description == null ? "" : custom_description);

    out.writeInt(icon.getRowBytes());
    out.writeInt(icon.getHeight());
    out.writeInt(icon.getWidth());
    out.writeInt(icon.getConfig().ordinal());

    final int bmSize = icon.getRowBytes() * icon.getHeight();
    if (dst == null || bmSize > dst.capacity()) {
        dst = ByteBuffer.allocate(bmSize);
    }
    dst.rewind();
    icon.copyPixelsToBuffer(dst);
    dst.flip();
    out.write(dst.array(), 0, bmSize);
}


private synchronized void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
    title = in.readUTF();
    url_friendly_name = in.readUTF();
    creator_name = in.readUTF();
    version = in.readUTF();
    package_name = in.readUTF();
    contact_website = in.readUTF();
    popularity = in.readInt();
    inconditional_redirect = in.readUTF();
    custom_description = in.readUTF();

    final int nbRowBytes = in.readInt();
    final int height = in.readInt();
    final int width = in.readInt();
    final Bitmap.Config config = Bitmap.Config.values()[in.readInt()];

    final int bmSize = nbRowBytes * height;
    if (dst == null || bmSize > dst.capacity()) {
        dst = ByteBuffer.allocate(bmSize);
    }
    dst.rewind();
    in.read(dst.array(), 0, bmSize);

    icon = Bitmap.createBitmap(width, height, config);
    icon.copyPixelsFromBuffer(dst);
}
...