Android Jni 利用OpenCV 实现图像任意角度旋转

一,java代码,收集Bitmap 信息

private Button btnProc;
private ImageView imageView;
private Bitmap bmp;

// Used to load the 'native-lib' library on application startup.
static {
    System.loadLibrary("native-lib");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example of a call to a native method
    btnProc = (Button) findViewById(R.id.btn_gray_process);
    imageView = (ImageView) findViewById(R.id.image_view);

    bmp = BitmapFactory.decodeResource(getResources(), R.drawable.test7);
    imageView.setImageBitmap(bmp);
    btnProc.setOnClickListener(this);
}

/**
 * A native method that is implemented by the 'native-lib' native library,
 * which is packaged with this application.
 */
public static native int[] grayProc(int[] pixels, int w, int h);


@Override
public void onClick(View view) {

    int w = bmp.getWidth();
    int h = bmp.getHeight();
    int[] pixels = new int[w*h];
    bmp.getPixels(pixels, 0, w, 0, 0, w, h);

    long startTime = System.currentTimeMillis();
    int[] resultInt = grayProc(pixels, w, h);
    long endTime = System.currentTimeMillis();

    Log.e("JNITime",""+(endTime-startTime));
    Bitmap resultImg = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

    //(@ColorInt int[] pixels, int offset, int stride,int x, int y, int width, int height)
    resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);
    imageView.setImageBitmap(resultImg);

}

二,jni实现

using namespace std;
using namespace cv;

Mat rotateImage1(Mat img, int degree){

degree = -degree;
double angle = degree  * CV_PI / 180.; // 弧度

//获取弧度对应的三角函数值
double a = sin(angle);
double b = cos(angle);

//获取矩阵的宽高
int width = img.cols;
int height = img.rows;

int width_rotate = int(height * fabs(a) + width * fabs(b));
int height_rotate = int(width * fabs(a) + height * fabs(b));

float map[6];
Mat map_matrix = Mat(2, 3, CV_32F, map);

// 旋转中心
CvPoint2D32f center = cvPoint2D32f(width / 2 +0.5, height / 2 +0.5);
CvMat map_matrix2 = map_matrix;

//( CvPoint2D32f center, double angle, double scale, CvMat* map_matrix );
cv2DRotationMatrix(center, degree, 1.0, &map_matrix2);

Mat img_rotate;
//CV_WARP_FILL_OUTLIERS - 填充所有输出图像的象素。
//如果部分象素落在输入图像的边界外,那么它们的值设定为 fillval.
//CV_WARP_INVERSE_MAP - 指定 map_matrix 是输出图像到输入图像的反变换,

//( InputArray src, OutputArray dst, InputArray M, Size dsize,
warpAffine(img, img_rotate, map_matrix, Size(width_rotate, height_rotate));
return img_rotate;

}

extern “C”
JNIEXPORT jintArray JNICALL
Java_com_example_dgxq008_opencv_1readpixel_MainActivity_grayProc(JNIEnv *env, jclass type
, jintArray pixels_
, jint w
, jint h) {

jint* pixels = env->GetIntArrayElements(pixels_, NULL);
if (pixels==NULL){
    return 0;
}


//图片一进来时是ARGB  通过mat转换BGRA
Mat img(h,w,CV_8UC4,(uchar *)pixels);  //pixels 操作的是同一份数据
Mat temp;

 //传入自己要实现的角度,这里实现倒影效果
int degree = 180;

//其实现方法,是从网上搜的工具方法
Mat m_ResImg = rotateImage1(img, degree);
resize(m_ResImg,img,Size( img.cols, img.rows ));

//对应数据指针
int size = w*h;
jintArray result = env->NewIntArray(size);
env->SetIntArrayRegion(result,0,size,pixels);

env->ReleaseIntArrayElements(pixels_, pixels, 0);

return result;

}

你可能感兴趣的:(Android Jni 利用OpenCV 实现图像任意角度旋转)