先上效果图:
| |
|
主要是卡在调用手机相册图片,因为手机是Android9系统,访问相册需要申请权限.另外,图片的处理还是挺头疼的.
这是测试OpenCV环境是否搭好的测试app,虽然只是测试,尽量做到尽善尽美.
整个界面很简单:
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
tools:context=".ProcessImageActivity">
<LinearLayout
android:id="@+id/btn_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:orientation="horizontal">
<Button
android:id="@+id/select_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/img"
android:layout_weight="1"
android:text="选择图片" />"
<Button
android:id="@+id/gray_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/img"
android:layout_weight="1"
android:text="灰度化" />"
</LinearLayout>
<ImageView
android:id="@+id/img"
android:layout_below="@+id/btn_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:src="@drawable/tayler"/>
</RelativeLayout>
调用相册图片
首先在android9.0的机子上,肯定是要进行动态权限申请的.
整理一下动态申请权限的语句:
这是一块模板,可以在String permission[]中添加一些权限
private void requirePermission(){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
if (ActivityCompat.checkSelfPermission(MainActivity.this, permission)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission},123);
}
}
}
访问相册
intent跳转,隐式跳转
Intent albumIntent = new Intent(Intent.ACTION_GET_CONTENT);
albumIntent.addCategory(Intent.CATEGORY_OPENABLE); //调用相册
albumIntent.setType("image/jpeg");
startActivityForResult(albumIntent, REQUEST_CODE_IMAGE);
跳转到startActivity后,具体的操作设计到对图片的操作.
这里的操作很多,因为imageview提供的方法很多,
使用setImageBitmap(),会出现图片无法显示的结果,可能原因是图片质量太大.需要对图片进行处理.
这里用到的是imageUtil工具,就是将一些方法封装成类.
if (requestCode == 2 && resultCode == RESULT_OK) {
Uri mPath = data.getData();
if(imageUtil == null){
imageUtil = new ImageUtil(this);
}
String file = imageUtil.getPath(mPath);
Bitmap bitmap = imageUtil.decodeImage(file);
if (bitmap == null) {
return;
}
Log.i(TAG, "width=" + bitmap.getWidth() + ",height=" + bitmap.getHeight());
imageView.setImageBitmap(bitmap);
}
imageUtil类中的getPath()方法.
public String getPath(Uri uri) {
if (DocumentsContract.isDocumentUri(context, uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
String[] projection = { MediaStore.Images.Media.DATA };
Cursor imageCursor = ((Activity)context).managedQuery(uri, projection, null, null, null);
int actual_image_column_index = imageCursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
imageCursor.moveToFirst();
String img_path = imageCursor.getString(actual_image_column_index);
String end = img_path.substring(img_path.length() - 4);
if (0 != end.compareToIgnoreCase(".jpg") && 0 != end.compareToIgnoreCase(".png")) {
return null;
}
return img_path;
}
imageUtil类中的decodeimage()方法.
public Bitmap decodeImage(String path) {
Bitmap res;
try {
ExifInterface exif = new ExifInterface(path);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
BitmapFactory.Options op = new BitmapFactory.Options();
op.inSampleSize = 1;
op.inJustDecodeBounds = false;
res = BitmapFactory.decodeFile(path, op);
Matrix matrix = new Matrix();
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
matrix.postRotate(90);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
matrix.postRotate(180);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
matrix.postRotate(270);
}
Bitmap temp = Bitmap.createBitmap(res, 0, 0, res.getWidth(), res.getHeight(), matrix, true);
Log.i(TAG, "check target Image:" + temp.getWidth() + "*" + temp.getHeight());
if (!temp.equals(res)) {
res.recycle();
}
return temp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
上面内容与OpenCV毫无关系,纯Android内容
进入OpenCV 测试
其实就几行代码,因为都是用api.
核心内容:灰度化,网上都有.
public void processGray()
{
Mat src=new Mat();
Mat dst=new Mat();
Bitmap tmp=selectBitmap.copy(selectBitmap.getConfig(),true);
dstBitmap= Bitmap.createBitmap(tmp.getWidth(),tmp.getHeight(), Bitmap.Config.RGB_565);
Utils.bitmapToMat(selectBitmap,src);
Imgproc.cvtColor(src,dst,Imgproc.COLOR_BGRA2GRAY);
Utils.matToBitmap(dst,dstBitmap);
}