Android Bitmap's format and IplImage's format matching is very important

最近在做录像的项目,通过bitmap.copyPixelsToBuffer老是出现java.lang.RuntimeException: Buffer not large enough for pixels的错误。查找了一下原因。
 
Android Bitmap's format and IplImage's format matching is very important.
 
 
JavaCV处理图像格式多为IplImage格式,而Android程序里的ImageView组件无法直接显示IplImage格式图像,所以需要转化格式。通过将图片像素载入buffer的方式,实现将Bitmap格式图片转换为IplImage格式图片。建立4通道IplImage图像对应Bitmap数据格式为ARGB_8888;建立2通道IplImage图像对应Bitmap数据格式为RGB_565
 
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	
	LinearLayout layout = (LinearLayout)findViewById(R.id.root);
	ImageView image = new ImageView(this);
	layout.addView(image);

	Bitmap bitmapIn = BitmapFactory.decodeResource(getResources(), R.drawable.abc);
	IplImage newin = IplImage.create(bitmapIn.getWidth(), bitmapIn.getHeight(), IPL_DEPTH_8U, 4);
	bitmapIn.copyPixelsToBuffer(newin.getByteBuffer()); 
	
	cvFlip(newin, newout, 0);//图像旋转
	
	IplImage newout = IplImage.create(bitmapIn.getWidth(), bitmapIn.getHeight(),IPL_DEPTH_8U, 4);
	Bitmap bitmapOut = Bitmap.createBitmap(bitmapIn.getWidth(), bitmapIn.getHeight(), Bitmap.Config.ARGB_8888);
	bitmapOut.copyPixelsFromBuffer(newout.getByteBuffer());
	image.setImageBitmap(bitmapOut);
}

IplImage image = IplImage.create(width, height, IPL_DEPTH_8U, 4);IplImage _3image = IplImage.create(width, height, IPL_DEPTH_8U, 3);IplImage _1image = IplImage.create(width, height, IPL_DEPTH_8U, 1);Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);1. iplimage -> bitmapbitmap.copyPixelsFromBuffer(image.getByteBuffer());2. bitmap -> iplimagebitmap.copyPixelsToBuffer(image.getByteBuffer());3. iplimage(4channel) -> iplimage(3channel or 1channel)cvCvtColor(image, _3image, CV_BGRA2BGR);cvCvtColor(_3image, _1image, CV_RGB2GRAY);-----------------------------------------------------------------------------------Create iplimage from Android's camera byte[] dataprivate IplImage _4iplToBitmap;_4iplToBitmap = IplImage.create(width, height, IPL_DEPTH_8U, 4);int [] _temp = new int[width*height];if(_4iplToBitmap!= null){ decodeYUV420SP(_temp, data, width, height); _4iplToBitmap.getIntBuffer().put(_temp);}protected void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { int frameSize = width * height; for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; for (int i = 0; i < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; rgb[yp] = 0xff000000 | ((b << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((r >> 10) & 0xff); } }}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值