mirror of
https://github.com/opencv/opencv.git
synced 2025-08-01 02:18:01 +08:00
android: use .getRowStride() in JavaCamera2View
This commit is contained in:
parent
d8ab83600b
commit
80c4cedd25
@ -41,6 +41,15 @@ public class Mat {
|
||||
nativeObj = n_Mat(rows, cols, type, data);
|
||||
}
|
||||
|
||||
//
|
||||
// C++: Mat::Mat(int rows, int cols, int type, void* data, size_t step)
|
||||
//
|
||||
|
||||
// javadoc: Mat::Mat(rows, cols, type, data, step)
|
||||
public Mat(int rows, int cols, int type, ByteBuffer data, long step) {
|
||||
nativeObj = n_Mat(rows, cols, type, data, step);
|
||||
}
|
||||
|
||||
//
|
||||
// C++: Mat::Mat(Size size, int type)
|
||||
//
|
||||
@ -1136,6 +1145,9 @@ public class Mat {
|
||||
// C++: Mat::Mat(int rows, int cols, int type, void* data)
|
||||
private static native long n_Mat(int rows, int cols, int type, ByteBuffer data);
|
||||
|
||||
// C++: Mat::Mat(int rows, int cols, int type, void* data, size_t step)
|
||||
private static native long n_Mat(int rows, int cols, int type, ByteBuffer data, long step);
|
||||
|
||||
// C++: Mat::Mat(Size size, int type)
|
||||
private static native long n_Mat(double size_width, double size_height, int type);
|
||||
|
||||
|
@ -1246,4 +1246,22 @@ public class MatTest extends OpenCVTestCase {
|
||||
assertEquals(1, bbuf.get(4095));
|
||||
}
|
||||
|
||||
public void testMatFromByteBufferWithStep() {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(80*64);
|
||||
bbuf.putInt(0x01010101);
|
||||
bbuf.putInt(64, 0x02020202);
|
||||
bbuf.putInt(80, 0x03030303);
|
||||
Mat m = new Mat(64, 64, CvType.CV_8UC1, bbuf, 80);
|
||||
assertEquals(8, Core.countNonZero(m));
|
||||
Core.add(m, new Scalar(5), m);
|
||||
assertEquals(4096, Core.countNonZero(m));
|
||||
m.release();
|
||||
assertEquals(6, bbuf.get(0));
|
||||
assertEquals(5, bbuf.get(63));
|
||||
assertEquals(2, bbuf.get(64));
|
||||
assertEquals(0, bbuf.get(79));
|
||||
assertEquals(8, bbuf.get(80));
|
||||
assertEquals(5, bbuf.get(63*80 + 63));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -332,8 +332,10 @@ public class JavaCamera2View extends CameraBridgeViewBase {
|
||||
Image.Plane[] planes = mImage.getPlanes();
|
||||
int w = mImage.getWidth();
|
||||
int h = mImage.getHeight();
|
||||
assert(planes[0].getPixelStride() == 1);
|
||||
ByteBuffer y_plane = planes[0].getBuffer();
|
||||
mGray = new Mat(h, w, CvType.CV_8UC1, y_plane);
|
||||
int y_plane_step = planes[0].getRowStride();
|
||||
mGray = new Mat(h, w, CvType.CV_8UC1, y_plane, y_plane_step);
|
||||
return mGray;
|
||||
}
|
||||
|
||||
@ -349,11 +351,14 @@ public class JavaCamera2View extends CameraBridgeViewBase {
|
||||
assert(planes[0].getPixelStride() == 1);
|
||||
assert(planes[2].getPixelStride() == 2);
|
||||
ByteBuffer y_plane = planes[0].getBuffer();
|
||||
int y_plane_step = planes[0].getRowStride();
|
||||
ByteBuffer uv_plane1 = planes[1].getBuffer();
|
||||
int uv_plane1_step = planes[1].getRowStride();
|
||||
ByteBuffer uv_plane2 = planes[2].getBuffer();
|
||||
Mat y_mat = new Mat(h, w, CvType.CV_8UC1, y_plane);
|
||||
Mat uv_mat1 = new Mat(h / 2, w / 2, CvType.CV_8UC2, uv_plane1);
|
||||
Mat uv_mat2 = new Mat(h / 2, w / 2, CvType.CV_8UC2, uv_plane2);
|
||||
int uv_plane2_step = planes[2].getRowStride();
|
||||
Mat y_mat = new Mat(h, w, CvType.CV_8UC1, y_plane, y_plane_step);
|
||||
Mat uv_mat1 = new Mat(h / 2, w / 2, CvType.CV_8UC2, uv_plane1, uv_plane1_step);
|
||||
Mat uv_mat2 = new Mat(h / 2, w / 2, CvType.CV_8UC2, uv_plane2, uv_plane2_step);
|
||||
long addr_diff = uv_mat2.dataAddr() - uv_mat1.dataAddr();
|
||||
if (addr_diff > 0) {
|
||||
assert(addr_diff == 1);
|
||||
@ -369,30 +374,45 @@ public class JavaCamera2View extends CameraBridgeViewBase {
|
||||
ByteBuffer u_plane = planes[1].getBuffer();
|
||||
ByteBuffer v_plane = planes[2].getBuffer();
|
||||
|
||||
y_plane.get(yuv_bytes, 0, w*h);
|
||||
int yuv_bytes_offset = 0;
|
||||
|
||||
int y_plane_step = planes[0].getRowStride();
|
||||
if (y_plane_step == w) {
|
||||
y_plane.get(yuv_bytes, 0, w*h);
|
||||
yuv_bytes_offset = w*h;
|
||||
} else {
|
||||
int padding = y_plane_step - w;
|
||||
for (int i = 0; i < h; i++){
|
||||
y_plane.get(yuv_bytes, yuv_bytes_offset, w);
|
||||
yuv_bytes_offset += w;
|
||||
if (i < h - 1) {
|
||||
y_plane.position(y_plane.position() + padding);
|
||||
}
|
||||
}
|
||||
assert(yuv_bytes_offset == w * h);
|
||||
}
|
||||
|
||||
int chromaRowStride = planes[1].getRowStride();
|
||||
int chromaRowPadding = chromaRowStride - w/2;
|
||||
|
||||
int offset = w*h;
|
||||
if (chromaRowPadding == 0){
|
||||
// When the row stride of the chroma channels equals their width, we can copy
|
||||
// the entire channels in one go
|
||||
u_plane.get(yuv_bytes, offset, w*h/4);
|
||||
offset += w*h/4;
|
||||
v_plane.get(yuv_bytes, offset, w*h/4);
|
||||
u_plane.get(yuv_bytes, yuv_bytes_offset, w*h/4);
|
||||
yuv_bytes_offset += w*h/4;
|
||||
v_plane.get(yuv_bytes, yuv_bytes_offset, w*h/4);
|
||||
} else {
|
||||
// When not equal, we need to copy the channels row by row
|
||||
for (int i = 0; i < h/2; i++){
|
||||
u_plane.get(yuv_bytes, offset, w/2);
|
||||
offset += w/2;
|
||||
u_plane.get(yuv_bytes, yuv_bytes_offset, w/2);
|
||||
yuv_bytes_offset += w/2;
|
||||
if (i < h/2-1){
|
||||
u_plane.position(u_plane.position() + chromaRowPadding);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < h/2; i++){
|
||||
v_plane.get(yuv_bytes, offset, w/2);
|
||||
offset += w/2;
|
||||
v_plane.get(yuv_bytes, yuv_bytes_offset, w/2);
|
||||
yuv_bytes_offset += w/2;
|
||||
if (i < h/2-1){
|
||||
v_plane.position(v_plane.position() + chromaRowPadding);
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__IIILjava_nio_ByteBuffer
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__IIILjava_nio_ByteBuffer_2
|
||||
(JNIEnv* env, jclass, jint rows, jint cols, jint type, jobject data)
|
||||
{
|
||||
static const char method_name[] = "Mat::n_1Mat__IIILByteBuffer()";
|
||||
static const char method_name[] = "Mat::n_1Mat__IIILjava_nio_ByteBuffer_2()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
return (jlong) new Mat( rows, cols, type, (void*)env->GetDirectBufferAddress(data) );
|
||||
@ -88,6 +88,32 @@ JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__IIILjava_nio_ByteBuffer
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: org_opencv_core_Mat
|
||||
* Method: n_Mat
|
||||
* Signature: (IIILjava/nio/ByteBuffer;J)J
|
||||
*
|
||||
* Mat::Mat(int rows, int cols, int type, void* data, size_t step)
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__IIILjava_nio_ByteBuffer_2J
|
||||
(JNIEnv* env, jclass, jint rows, jint cols, jint type, jobject data, jlong step);
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__IIILjava_nio_ByteBuffer_2J
|
||||
(JNIEnv* env, jclass, jint rows, jint cols, jint type, jobject data, jlong step)
|
||||
{
|
||||
static const char method_name[] = "Mat::n_1Mat__IIILjava_nio_ByteBuffer_2J()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
return (jlong) new Mat(rows, cols, type, (void*)env->GetDirectBufferAddress(data), (size_t)step);
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Mat::Mat(int rows, int cols, int type)
|
||||
|
Loading…
Reference in New Issue
Block a user