0

I have a basic Hashmap code that wont work for some reason.

ConcurrentHashMap<Bitmap, byte[]> pixels = new ConcurrentHashMap<Bitmap, byte[]>();

it key is bitmap, and the value are its bytes that I get using this code:

public byte[] getPixels(Bitmap bmp) {
    int bytes = bmp.getRowBytes() * bmp.getHeight();
 buffer = ByteBuffer.allocateDirect(bytes);
    bmp.copyPixelsToBuffer(buffer);
    buffer.clear();
    return buffer.array();
}

In the hashmap for all the bitmaps I have I put:

    pixels.put(bitmap1, getPixels(b)); 

And when I want to get the value (bytes) back I do:

    byte[] pixelData = pixels.get(bitmap1);

and for some odd reason its always null!, why? I tried on different bitmaps, they all return null, and it is the same bitmap..

SpoocyCrep
  • 576
  • 4
  • 22
  • Erm... You can't call `.array()` on a directly allocated `ByteBuffer`. There's something else going on. – fge Mar 23 '15 at 10:35
  • @fge I can, the code is working and worked before I used hashmap. It is part of this solution: http://stackoverflow.com/a/29061657/4024143 – SpoocyCrep Mar 23 '15 at 10:39

3 Answers3

1

It must be the same instance of Bitmap. If you create another instance of same Bitmap, it'll not be the same object.

For instance:

Bitmap b1 = BitmapFactory.decodeFile("mybitmap.png");
ConcurrentHashMap<Bitmap, byte[]> pixels = new ConcurrentHashMap<Bitmap, byte[]>();
pixels.add(b1);
[...]
Bitmap b2 = BitmapFactory.decodeFile("mybitmap.png");
byte[] barray1 = pixels.get(b1);
byte[] barray2 = pixels.get(b2);

barray1 is not null

barray2 is null

LaurentY
  • 6,959
  • 3
  • 34
  • 53
  • and if I say b2=b1; and give b2 will it return null? because thats how it is in my code,I don't have new decoded files, I use the same bitmaps. – SpoocyCrep Mar 23 '15 at 10:46
  • @SpoocyCrep, If bitmap is not "recreate" (new instance or coy from BitmapFactory or Bitmap) it have to work – LaurentY Mar 23 '15 at 10:56
  • You're right, I've found my mistake - I rescaled the bitmap after inserting it to the hashmap without noticing. I've added it after the rescale and it works. – SpoocyCrep Mar 23 '15 at 11:04
1

First things: the javadoc of Android's Bitmap makes no guarantee that it supports equals() and hashCode() if they have the same content, which means that if they don't, you're screwed.

Second: the javadoc of ByteBuffer.allocateDirect() states that:

Whether or not it has a backing array is unspecified.

Therefore --> don't use that, use ByteBuffer.allocate() instead which is guaranteed to have a backing array.

But I guess the problem is with the first point.

fge
  • 110,072
  • 26
  • 223
  • 312
  • Okay, I changed it to allocate but the problem stays the same. I don't say two different bitmaps with same content, the bitmaps are all pointing at the same bitmap, on create I load some bitmaps and send them to classes. I do not change the bitmap so its really weird.. – SpoocyCrep Mar 23 '15 at 10:49
1

Whenever you use a HashMap and you treat a certain type of object as a key, you need to consider whether that object's equals() method is designed properly for custom equality checks. In most cases it is not, so you need to re-implement the equals() method.

The prevailing logic in Java is that when you override equals(), you must also override the hashCode() method. (See this post)

In other words, you need to derive a class CustomBitmap from Bitmap and add new implementations of equals() and hashCode() to the new class. Then it can be used successfully as a key in a HashMap.

Community
  • 1
  • 1
Y.S
  • 28,153
  • 12
  • 86
  • 113