android how to save a bitmap - buggy code

后端 未结 3 2036
伪装坚强ぢ
伪装坚强ぢ 2020-11-30 11:03

Im trying to serialize a class in wich i have a bitmap variable. Here is the code that is a bit working.... I need help to find out what is still wrong.....

         


        
相关标签:
3条回答
  • 2020-11-30 11:09

    No need to have the redundant array + all the logic around + use the given methods to manipulate the buffer + utf is better for strings and avoid the casts + synchronization (but it is not thread safe anyway) :

    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);
    }
    
    0 讨论(0)
  • 2020-11-30 11:11

    To simplify things, you can use standard serialization for all fields other than the bitmap. Just mark the bitmap as transient, and use out.defaultWriteObject(); and in.defaultReadObject();. This really cleans up the code:

    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);
    }
    
    0 讨论(0)
  • 2020-11-30 11:29

    Here is the code for a serialization with memory optimisation. Im using a static buffer that is growing to the biggest bitmap size and that I reuse each time.

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

    }

    0 讨论(0)
提交回复
热议问题