Hi I wanna convert byte array to bitmap and show image in a ImageView. I wrote the following code but I got exception that says that the buffer not large enough for pixels.
Image resolution : 480*640
ARGB = 480*640\*4 = 1228800????
bitmap = Bitmap.createBitmap(480,640, Bitmap.Config.ARGB_8888);
byte[] temp = Arrays.copyOfRange(bytes,745488,1228800);
ByteBuffer buffer = ByteBuffer.wrap(temp);
bitmap.copyPixelsFromBuffer(buffer);
imageView.setImageBitmap(bitmap);
Error:
java.lang.RuntimeException: Buffer not large enough for pixels at android.graphics.Bitmap.copyPixelsFromBuffer(Bitmap.java:567) at com.example.scratch.HomeActivity$3.run(HomeActivity.java:119) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6121) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Android/Java:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blendmode);
app = (MessiApplication) this.getApplication();
blendModeRawStreamBitmap = Bitmap.createBitmap(app.getVideoWidth(),app.getVideoHeight(), Bitmap.Config.ARGB_8888);
blendModeColorStreamBitmap = Bitmap.createBitmap(app.getVideoWidth(),app.getVideoHeight(), Bitmap.Config.ARGB_8888);
blendModeRawStreamImageView = findViewById(R.id.blend_mode_raw_video_view_id);
blendModeColorStreamImageView = findViewById(R.id.blend_mode_color_video_view_id);
videoStreamInfo = new VideoStreamInfo(app.getVideoWidth() , app.getVideoHeight(), app.getRawPseudoOffset(), 0);
}
private int _onAllVideoFrame(int cmd, String [] path, byte[] rawBytes, byte[] colorBytes)
{
runOnUiThread(new Runnable(){
@Override
public void run() {
ByteBuffer rawStreamBuffer = ByteBuffer.wrap(rawBytes);
blendModeRawStreamBitmap.copyPixelsFromBuffer(rawStreamBuffer);
blendModeRawStreamImageView.setImageBitmap(blendModeRawStreamBitmap);
ByteBuffer colorStreamBuffer = ByteBuffer.wrap(colorBytes);
blendModeColorStreamBitmap.copyPixelsFromBuffer(colorStreamBuffer);
blendModeColorStreamImageView.setImageBitmap(blendModeColorStreamBitmap);
}
});
return 0;
}
Jni/C++:
jbyteArray color_frame_buffer = NULL;
jbyteArray raw_frame_buffer = NULL;
raw_frame_buffer = (jbyteArray)cb->env->GetObjectField(cb->video_stream_obj, cb->raw_buffer_dield_id);
if(raw_frame_buffer == NULL)
{
ALOGE("Fail to get raw_frame_buffer field");
return -1;
}
cb->env->SetByteArrayRegion(raw_frame_buffer,0, cb->raw_stream_buffer_size,(jbyte *)req.text + cb->raw_stream_buffer_offset);
cb->env->SetDoubleField(cb->video_stream_obj,cb->raw_fps_dield_id,video_stream_info.fps);
cb->env->SetDoubleField(cb->video_stream_obj,cb->raw_jitter_dield_id,video_stream_info.jitter);
color_frame_buffer = (jbyteArray)cb->env->GetObjectField(cb->video_stream_obj,cb->color_buffer_dield_id);
if(color_frame_buffer == NULL)
{
ALOGE("Fail to get color_frame_buffer field");
return -1;
}
rgba_buffer = (uint8_t*)malloc(cb->color_stream_buffer_size);
if(rgba_buffer == nullptr)
{
ALOGE("Not enough memory field.");
return -1;
}
memset(rgba_buffer, 0, cb->color_stream_buffer_size);
Yuv422ToRgba(cb->color_video_width, cb->color_video_height, (uint8_t*)req.text + cb->color_stream_buffer_offset, rgba_buffer);
cb->env->SetByteArrayRegion(color_frame_buffer,0, cb->color_stream_buffer_size, (jbyte *)rgba_buffer);
cb->env->CallIntMethod(cb->obj,cb->on_frame_function_id,cmd,jpath_obj, raw_frame_buffer, color_frame_buffer);
YuvToRgba
void Yuv422ToRgba(int width, int heigth, uint8_t *yuv_buffer, uint8_t* rbga_buffer)
{
int pixel_size = width*heigth;
uint32_t *pixel_ptr = (uint32_t *)rbga_buffer;
uint8_t *y1_byte, *y2_byte, *u_byte, *v_byte;
uint8_t r_byte, g_byte, b_byte;
for (int y_itr = 0; y_itr < pixel_size * 2; y_itr += 4)
{
u_byte = yuv_buffer + y_itr;
y1_byte = yuv_buffer + y_itr + 1;
v_byte = yuv_buffer + y_itr + 2;
y2_byte = yuv_buffer + y_itr + 3;
r_byte = *y1_byte + 1.4023 * (*v_byte-128.0);
g_byte = *y1_byte - 0.3456 * (*u_byte-128.0) - 0.7145 * (*v_byte-128.0);
b_byte = *y1_byte + 1.771 * (*u_byte-128.0);
*pixel_ptr = 0x00000000 | r_byte << 16 | g_byte << 8 | b_byte;
pixel_ptr ++;
r_byte = *y2_byte + 1.4023 * (*v_byte-128.0);
g_byte = *y2_byte - 0.3456 * (*u_byte-128.0) - 0.7145 * (*v_byte-128.0);
b_byte = *y2_byte + 1.771 * (*u_byte-128.0);
*pixel_ptr = 0x00000000 | r_byte << 16 | g_byte << 8 | b_byte;
pixel_ptr ++;
}
}