[英]How to load image from my phone using OpenCV with Android Studio?
I am developing an android app using opencv in android studio,I follow the instruction in the book 'OpenCV Android Programming By Example' to code for loading an image from my phone.But I can't show it on ImageView though the code is exactly the same as the book,the main code is following: 我正在android studio中使用opencv开发一个android应用程序,我按照《 OpenCV Android示例编程》一书中的说明进行了从手机中加载图像的代码。尽管代码完全正确,但我无法在ImageView上显示它与本书相同,主要代码如下:
@Override
onCreate(...){...}
..........
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.read_img) {
Intent intent=new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"),
SELECT_PICTURE);
return true;
}
return super.onOptionsItemSelected(item);
}
public void onActivityResult(int requeseCode,int resultCode,Intent data){
if(resultCode==RESULT_OK){
if(requeseCode==SELECT_PICTURE){
Uri selectedImgUri=data.getData();
selectedImagePath=getPath(selectedImgUri);
loadImage(selectedImagePath);//the method to get the image
displayImage(sampledImage);//to display the image on ImageView
}
}
}
............
getPath(String path){.....}//it works fine
public void loadImage(String path){
Mat originalImage=Imgcodecs.imread(path);
Mat rgbImage=new Mat();
Imgproc.cvtColor(originalImage, rgbImage, Imgproc.COLOR_BGR2RGB);
//to reshape the image.
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width=size.x;
int height=size.y;
sampledImage=new Mat();
double downSampleRatio=calculateSubSampleSize(rgbImage,width,height);
Imgproc.resize(rgbImage,sampledImage,new Size(),downSampleRatio,downSampleRatio,Imgproc.INTER_AREA);
//to rotate the image,seems not a problem in this case.
try {
ExifInterface exif = new ExifInterface(selectedImagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
switch (orientation){
case ExifInterface.ORIENTATION_ROTATE_90:
sampledImage=sampledImage.t();
Core.flip(sampledImage, sampledImage, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
sampledImage=sampledImage.t();
Core.flip(sampledImage, sampledImage, 0);
break;}
} catch (IOException e){
e.printStackTrace();
}
}
public void displayImage(Mat image){
Bitmap bitmap=Bitmap.createBitmap(image.cols(),image.rows(),Bitmap.Config.RGB_565);
Utils.matToBitmap(image,bitmap);
ImageView imageView2=(ImageView)findViewById(R.id.imageView2);
imageView2.setImageBitmap(bitmap);
}
private static double calculateSubSampleSize(Mat srcImage, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = srcImage.height();
final int width = srcImage.width();
double inSampleSize = 1;
if(height>reqHeight|| width > reqWidth) {
// Calculate ratios of requested height and width to the raw height and width
final double heightRatio = (double) reqHeight / (double) height;
final double widthRatio = (double) reqWidth / (double) width;
// Choose the smallest ratio as inSampleSize value, this will //guarantee final image with both dimensions larger than or //equal to the requested height and width.
inSampleSize = heightRatio<widthRatio ? heightRatio :widthRatio;
} return inSampleSize;
} } }}
The app can run,but when i choose the image and click OK on my phone,it crashes,the logcat shows: 该应用程序可以运行,但是当我选择图像并在手机上单击“确定”时,它崩溃了,logcat显示:
org.opencv.imgcodecs.Imgcodecs.imread(Imgcodecs.java:118)
at com.example.administrator.opencvdemo.MainActivity.loadImage(MainActivity.java:142)
at com.example.administrator.opencvdemo.MainActivity.onActivityResult(MainActivity.java:118)
at android.app.Activity.dispatchActivityResult(Activity.java:5652)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3600)
Obviously it's the problem of the loadImage() method,but I search google and every where without finding the good answer,i tried to fix it,but it's the same problem.Can someone know how to solve it?It got me crazy.Thanks a lot! 显然,这是loadImage()方法的问题,但是我在google和所有地方搜索时都没有找到好的答案,我试图修复它,但这是同一个问题。有人知道如何解决它吗?这让我发了疯。很多!
Have you checked for the application permissions on the Manifest ? 您是否已检查清单上的应用程序权限? I had the same issue loading a file from my external storage.
我从外部存储设备加载文件时遇到了同样的问题。
I added <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
to my AndroidManifest.xml
. 我在我的
AndroidManifest.xml
添加了<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
。 Since Android 6 you need to request permissions on runtime. 从Android 6开始,您需要在运行时请求权限。
I took care of thoose permissions on my MainActivity like the following 我在MainActivity上选择了以下权限:
package test;
import java.io.File;
import java.util.ArrayList;
import java.util.Map;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
public class MainActivity extends Activity implements OnClickListener, ActivityCompat.OnRequestPermissionsResultCallback {
private String TAG = "MainActivity";
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
} break;
default:
{
Log.i(TAG, "OpenCV loaded FAILURE");
super.onManagerConnected(status);
} break;
}
}
};
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] PERMISSIONS = {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
};
if(!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, 1);
}
// Do work
}
}
Hope it can help. 希望能有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.