您的位置:首页 > 移动开发 > Android开发

Android OpenCV实现图片叠加,水印

2013-07-25 14:23 459 查看
关于如何用纯OpenCV实现图片叠加的例子实在是太少,太多的是使用 C++,JNI实现的,如果要用C++的话,我们为啥不转行做C++

下面的例子基于 Android JavaCV 实现了在im_beauty 美女图片上 添加im_flower3 小花图片 并显示



需要在res/drawable目录下 放两个文件 im_beauty, im_flower3 注意im_flower3一定要比im_beauty图片尺寸要下小








package com.KyleOpencvImageAdd;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.Rect;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnClickListener {

private Mat mat1,mat2;
private ImageView iv1,iv2;
//用于显示两张图片叠加
private ImageView iv3;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//初始化图片显示
iv1=(ImageView)findViewById(R.id.imageView1);
iv1.setImageResource(R.drawable.im_beauty);

iv2=(ImageView)findViewById(R.id.imageView2);
iv2.setImageResource(R.drawable.im_flower3);

iv3=(ImageView)findViewById(R.id.imageView3);

btn=(Button)findViewById(R.id.button1);
btn.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {

@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i("", "OpenCV loaded successfully");

} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
//初始化函数库
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
}

@Override
public void onClick(View arg0) {
// 初始化数据
mat1 = new Mat();
mat2 = new Mat();
Mat mat1Sub = new Mat();

// 加载图片
Bitmap bt1 = BitmapFactory.decodeResource(getResources(),
R.drawable.im_beauty);
Bitmap bt2 = BitmapFactory.decodeResource(getResources(),
R.drawable.im_flower3);
Bitmap bt3 = null;

// 转换数据
Utils.bitmapToMat(bt1, mat1);
Utils.bitmapToMat(bt2, mat2);

/** 方法一加权 高级方式 可实现水印效果*********/

// mat1Sub=mat1.submat(0, mat2.rows(), 0, mat2.cols());
// Core.addWeighted(mat1Sub, 1, mat2, 0.3, 0., mat1Sub);

/** 方法二 求差 ********/

// submat(y坐标, 图片2的高, x坐标,图片2的宽);
// mat1Sub=mat1.submat(0, mat2.rows(), 0, mat2.cols());
// mat2.copyTo(mat1Sub);

/*** 方法三兴趣区域裁剪 **/
// 定义感兴趣区域Rect(x坐标,y坐标,图片2的宽,图片2的高)
Rect rec = new Rect(0, 0, mat2.cols(), mat2.rows());
// submat(y坐标, 图片2的高, x坐标,图片2的宽);
mat1Sub = mat1.submat(rec);
mat2.copyTo(mat1Sub);
//转化为android识别的图像数据注意bt3的宽高要和mat1一至
bt3 = Bitmap.createBitmap(mat1.cols(), mat1.rows(), Config.RGB_565);
Utils.matToBitmap(mat1, bt3);
iv3.setImageBitmap(bt3);

}

}


处理上 bitmap 与mat 的 一定要注意 图片的宽高一致不然容易 Exception

/cv::error()(17079): OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src.rows && info.width ==

(uint32_t)src.cols) in void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean), file

/home/reports/ci/slave/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp, line 97

/org.opencv.android.Utils(17079): nMatToBitmap catched cv::Exception: /home/reports/ci/slave/50-

SDK/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows &&

info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong,

jobject, jboolean)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐