3

I obtain raw camera data rawData of type byte[], format RGBA, size 640x480, 4 bytes per pixel, from a library function. And I need to convert it to a Bitmap and display in an ImageView on the screen.

What I do is the following:

byte[] JPEGData = convertToJpeg(rawData, 640, 480, 80);
Bitmap bitmap = BitmapFactory.decodeByteArray(JPEGData , 0, JPEGData .length);    
imageView.setImageBitmap(bitmap);

where convertToJpeg() function is:

    public static byte[] convertToJpeg(byte[] buffer, int w, int h, int quality) {
        YuvImage yuv_image = new YuvImage(buffer, ImageFormat.NV21, w, h, null);

        Rect rect = new Rect(0, 0, w, h);
        ByteArrayOutputStream output_stream = new ByteArrayOutputStream();
        yuv_image.compressToJpeg(rect, quality, output_stream);

        Bitmap sourceBmp = BitmapFactory.decodeByteArray(output_stream.toByteArray(), 0, output_stream.size());
        Bitmap destBmp = Bitmap.createScaledBitmap(sourceBmp, (int) (w * 0.75), (int) (h * 0.75), true);

        ByteArrayOutputStream pictureStream = new ByteArrayOutputStream();
        destBmp.compress(CompressFormat.JPEG, quality, pictureStream);
        byte[] pictureByteArray = pictureStream.toByteArray();

        return pictureByteArray;
    }

After decodeByteArray() call I have bitmap.getConfig() == ARGB_8888.

However, what I see on the screen is some chaotic picture, with some blurry green shapes of what's been in the original picture.

What's wrong with it?

  • Nobosy knows any solution ? – Alexander Shmuratko Aug 27 '14 at 08:32
  • It seems blurry simply because the content of the Bitmap is encoded (NV21 format I think). So if you try to view it as a png or jpg file, it won't work. You first need to decode it before saving it. – Simon Marquis Aug 27 '14 at 10:58
  • @Simon, Didn't understand you. Bitmap is further displayed in an ImageView as follows: `(imageView.setBitmap(bitmap));`. What should I do? – Alexander Shmuratko Aug 27 '14 at 11:06
  • You must decode it before. Using this instruction on a ImageView, it will try to decode it as a regular ARGB bitmap. But, the byte[] is not in ARGB format. (maybe something like YUYV) – Simon Marquis Aug 27 '14 at 11:07
  • @Simon, I do: 1) `byte[] JPEGData = convertToJpeg(rawData, ...);` where `convertToJpeg` is listed above. And 2) `Bitmap bitmap = BitmapFactory.decodeByteArray(JPEGData , 0, JPEGData .length);` Do I have to decode data, as you say, at step 1 or after step 3? – Alexander Shmuratko Aug 27 '14 at 11:28
  • You should do it at the begining. In your example `byte[] buffer` should be converted to ARGB format. I think that `compressToJpeg` is expecting to have a ARGB format – Simon Marquis Aug 27 '14 at 11:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60076/discussion-between-alexander-shmuratko-and-simon-marquis). – Alexander Shmuratko Aug 27 '14 at 11:38
  • @Simon, I've just checked `rawData` format - its `RGBA`. – Alexander Shmuratko Aug 27 '14 at 12:13

2 Answers2

7

The solution has turned out to be simple. And no need to convert to JPEG.

Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bm.copyPixelsFromBuffer(ByteBuffer.wrap(rawData));
  • 3
    I just try your code. But I am getting error "java.lang.RuntimeException: Buffer not large enough for pixels" @Alexander Shmuratko – Jigar Shekh Nov 06 '15 at 06:15
  • @JigarShekh Please check if your width and height are correct. :) – Sipty Dec 15 '15 at 11:26
  • @Sipty Wondering where you can find the height and width? – Pat Marx Mar 15 '16 at 22:53
  • If you have access to the camera settings, you can take the capture resolution from the setup directly. Or you can try getting it from the ImageReader, if you're using one as the output for the camera data. – Sipty Mar 17 '16 at 14:40
0

ByteBuffer().rewind to reset the buffer position to 0 than the "buffer not large enough for pixels" solved

Dante
  • 81
  • 1
  • 2