前面两个部分分别介绍了在AS上安装OpenCV的开发环境以及关于OpenCV的基本信息,本部分就来说一说使用OpenCV处理图像的一些基本准备工作。
我们知道在AS上开发Android的项目最后都会运行到模拟器或者移动终端上,我们这里要使用OpenCV来处理图片,那么首先的获取图像,这里可能主要分为两个大部分,一部分是图片来源于本地,另一个是图片来源于网络。关于从网络中获取图片这里就先不介绍,主要说一下通过设备自带的相机和本地文件来获取图像资源。这里其实在我之前的博客就有介绍,有兴趣的朋友可以转至摄像头调用与照片选择
1,相机获取图片
打开相机:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri fileUri = Uri.fromFile(new File(fielPath));
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAMERA_REQUEST_CODE);
获取照片:
Bitmap bitmap=BitmapFactory.decodeFile(filePath);
2,文件获取图片
打开文件选择:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "请选择图片"), FILE_REQUEST_CODE);
获取图片:
private String handleImageOnKitKat(Intent data) {
//获取资源定位符
Uri uri = data.getData();
//选择图片路径
String imagePath = null;
if (DocumentsContract.isDocumentUri(this, uri)) {
String docId = DocumentsContract.getDocumentId(uri);
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
String id = docId.split(":")[1];
String selection = MediaStore.Images.Media._ID + "=" + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
imagePath = getImagePath(contentUri, null);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
imagePath = getImagePath(uri, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
imagePath = uri.getPath();
}
return imagePath;
}
private String getImagePath(Uri externalContentUri, String selection) {
String path = null;
Cursor cursor = getContentResolver().query(externalContentUri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}
只需要将回调的Intent传进到handleImageOnKitKat方法中即可获取选择的图片路径。
3,图片压缩与旋转
压缩:
Bitmap.createScaledBitmap(bitmap,imgWidth,imgHeight, true)
旋转:
/**
*
* @param bitmap
* @return
*/
public static Bitmap rotateBitmap(Bitmap bitmap,float rotateAngle){
Matrix matrix = new Matrix();
matrix.setRotate(rotateAngle);
Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()
, matrix, true);
return newBitmap;
}
注意,在旋转图片的时候建议设置图片Bitmap宽高一样,否则在旋转的过程中可能会报异常,因为Bitmap就像一个容器,我们旋转的是里面的内容,外壳没有变化,如果原来是长方形,旋转之后外壳还是长方形,里面的东西变成了躺着的长方形,也就是宽高对调了,你是肯定放不进去的,这个时候就会出现异常,但是如果是正方形就不会(前提是以90度为单位旋转)。
4,示例
4.1 示例效果
4.2 实现代码
activity_main.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context="com.hfut.imagetoolsdemo.MainActivity">
<ImageView
android:id="@+id/image_show"
android:layout_width="match_parent"
android:layout_height="400sp" />
<Button
android:id="@+id/open_camera"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="openCamera"
android:text="打开相机" />
<Button
android:id="@+id/open_file"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="openFile"
android:text="选择文件" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="宽:" />
<EditText
android:id="@+id/bitmap_width"
android:layout_width="150sp"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="高:" />
<EditText
android:id="@+id/bitmap_height"
android:layout_width="150sp"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="changeSize"
android:text="调整大小" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="rotateImage"
android:text="旋转图片" />
</LinearLayout>
MainActivity.java 代码:
package com.hfut.imagetoolsdemo;
import android.Manifest;
import android.content.ContentUris;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author why
* @date 2018-12-1 12:14:56
*/
public class MainActivity extends AppCompatActivity {
ImageView imageView;
EditText imgWidth;
EditText imgHeight;
Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image_show);
imgWidth = findViewById(R.id.bitmap_width);
imgHeight = findViewById(R.id.bitmap_height);
}
public void openCamera(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri fileUri = Uri.fromFile(new File("mnt/sdcard/why.jpg"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, 1);
}
public void openFile(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "请选择图片"), 2);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1:
bitmap = BitmapFactory.decodeFile("mnt/sdcard/why.jpg");
imageView.setImageBitmap(bitmap);
break;
case 2:
String imagePath = handleImageOnKitKat(data);
bitmap = BitmapFactory.decodeFile(imagePath);
imageView.setImageBitmap(bitmap);
break;
}
}
public void changeSize(View view) {
if (imgHeight.getText().toString().equals("") || imgWidth.getText().toString().equals("")) {
Toast.makeText(this, "please enter the size info", Toast.LENGTH_SHORT).show();
} else {
bitmap = Bitmap.createScaledBitmap(bitmap,
Integer.parseInt(imgWidth.getText().toString()),
Integer.parseInt(imgHeight.getText().toString()), true);
imageView.setImageBitmap(bitmap);
}
}
public void rotateImage(View view) {
bitmap = rotateBitmap(bitmap, 90);
imageView.setImageBitmap(bitmap);
}
private String handleImageOnKitKat(Intent data) {
//获取资源定位符
Uri uri = data.getData();
//选择图片路径
String imagePath = null;
if (DocumentsContract.isDocumentUri(this, uri)) {
String docId = DocumentsContract.getDocumentId(uri);
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
String id = docId.split(":")[1];
String selection = MediaStore.Images.Media._ID + "=" + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
imagePath = getImagePath(contentUri, null);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
imagePath = getImagePath(uri, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
imagePath = uri.getPath();
}
return imagePath;
}
private String getImagePath(Uri externalContentUri, String selection) {
String path = null;
Cursor cursor = getContentResolver().query(externalContentUri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}
private Bitmap rotateBitmap(Bitmap bitmap, float rotateAngle) {
Matrix matrix = new Matrix();
matrix.setRotate(rotateAngle);
Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()
, matrix, true);
return newBitmap;
}
}
在配置文件中添加读写外部存储和相机的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
注意,因为我是在5.1 的系统上测试的,在6.0及以上请添加权限申请部分代码。到这里,获取本地图片最基本的部分就介绍完了。更多类容请查看:
下一篇:OpenCV中Mat与Android中Bitmap简介