Android 腾讯优图开发问题总结
2015-12-02 12:06
615 查看
Android 腾讯优图开发问题总结
接入优图检测人脸失败错误码SDK_IMAGE_FACEDETECT_FAILED -1101
具体表现
提供的getBitmap的问题
Bitmap旋转的问题
优图API正向识别
Android机型兼容性考虑
Android系统兼容性考虑
总结
注:下载优图Android SDK不是类似微信SDK一样给出Jar包和文档,而是直接将接口调用封装到Youtu.java文件中,测试项目用Android Studio创建,这里开发者按照自己的包结构将相关的源文件导入到Eclipse工程中。
提供的
以下是下载SDK中MainActivity.java中提供的getBitmap()方法:
这个方法事实上是控制获取Bitmap的宽高,应该是API的要求,不过经过测试后,并不能很好的进行压缩,比如我的
获取图片的基本数据。经过测试图片能够得到正确压缩。然而…
言归正传,只有继续调试:
这一次,我把需要检测的Bitmap对象写入SD卡根目录,终于发现问题关键:
腾讯优图的测试图片打开后人像都是正方向,而我用红米2A自拍来的图片是正时针旋转270度的治好劲椎病模式的图片。那么将Bitmap对象旋转-90度或者正270度试试?于是继续修改
我们首先获取旋转角度,根据不同的角度进行相应的旋转,如果旋转角度为0,则不旋转,这样,再次修改
至此基本上大功告成。在HTC one 801e 手机上测试,发现根本获取不了Bitmap对象,返回空指针错误。
怀疑是系统没有找到图片文件,我们知道调用系统相册将返回Uri数据,我们获取图片需要图片的路径,在腾讯优图的测试源码中, 提供了
重写
OK,这次可以开心的听听音乐,谢谢博客了。在我所拥有的的测试条件下(红米2A,魅族MX4,三星Note3,HTC one 801e),皆可以完成腾讯优图API的正确接入。
不同机型自拍保存图片方向(与不同厂商摄像头调教有关)
高低版本Android系统的兼容性问题
不得不说,现在Android开发很多东西都特别混乱,增加了开发难度。
接入优图检测人脸失败错误码SDK_IMAGE_FACEDETECT_FAILED -1101
具体表现
提供的getBitmap的问题
Bitmap旋转的问题
优图API正向识别
Android机型兼容性考虑
Android系统兼容性考虑
总结
Android 腾讯优图开发问题总结
马上要提交腾讯优图的第一次比赛的作品了,才匆匆忙忙开始这次项目,期间遇到不少问题,发现网上并没有相关解答,毕竟优图API比较新吧,用的人比较少。我就把我遇到的问题总结一下吧。接入优图检测人脸失败,错误码SDK_IMAGE_FACEDETECT_FAILED = -1101
具体表现
下载优图Android SDK,里面获取优图官方测试图片文件,检测返回数据正确,使用自己的自拍返回失败(刚开始还以为是自己长得丑检测不出来 TAT)注:下载优图Android SDK不是类似微信SDK一样给出Jar包和文档,而是直接将接口调用封装到Youtu.java文件中,测试项目用Android Studio创建,这里开发者按照自己的包结构将相关的源文件导入到Eclipse工程中。
提供的getBitmap()
的问题
以下是下载SDK中MainActivity.java中提供的getBitmap()方法:[code] private Bitmap getBitmap(String path , int maxWidth, int maxHeight){ //先解析图片边框的大小 BitmapFactory.Options ops = new BitmapFactory.Options(); ops.inJustDecodeBounds = true; ops.inSampleSize = 1; int oHeight = ops.outHeight; int oWidth = ops.outWidth; //控制压缩比 int contentHeight = maxWidth; int contentWidth = maxHeight; if(((float)oHeight/contentHeight) < ((float)oWidth/contentWidth)){ ops.inSampleSize = (int) Math.ceil((float)oWidth/contentWidth); }else{ ops.inSampleSize = (int) Math.ceil((float)oHeight/contentHeight); } ops.inJustDecodeBounds = false; Bitmap bm = BitmapFactory.decodeFile(path, ops); return bm; }
这个方法事实上是控制获取Bitmap的宽高,应该是API的要求,不过经过测试后,并不能很好的进行压缩,比如我的
红米2A测试机自拍得到的Bitmap是1200 * 1600,调用返回结果仍然是1200 * 1600。这里我们对上述方法进行修改,添加语句:
[code]ops.inJustDecodeBounds = true;// 防止Out Of Memory错误 Bitmap bm = BitmapFactory.decodeFile(path, ops);
获取图片的基本数据。经过测试图片能够得到正确压缩。然而…
Bitmap旋转的问题
优图API正向识别
接上然而…然而仍然返回错误码SDK_IMAGE_FACEDETECT_FAILED = -1101,这回真的是我长得丑没差了吧。。。然而用腾讯优图测试图片中葛大爷的图片居然都能检测出来。。。TAT言归正传,只有继续调试:
这一次,我把需要检测的Bitmap对象写入SD卡根目录,终于发现问题关键:
腾讯优图的测试图片打开后人像都是正方向,而我用红米2A自拍来的图片是正时针旋转270度的治好劲椎病模式的图片。那么将Bitmap对象旋转-90度或者正270度试试?于是继续修改
getBitmap方法:
[code]ops.inJustDecodeBounds = false; bm = BitmapFactory.decodeFile(path, ops); if (bm != null){ Matrix m = new Matrix(); m.setRotate(-90, (float) bm.getWidth() / 2,(float) bm.getHeight() / 2); Bitmap bm1 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),bm.getHeight(), m, true); return bm1;//旋转后的图片 }
Android机型兼容性考虑
我的红米2A测试机终于可以正确识别了,网络良好的情况下识别效率和识别的准确度还挺高的,但是…换了同学的MX4之后就又不行了。按照上述方法接着存图片,发现人家MX4自拍得来照片就是正向的,根本不需要旋转,如何解决这个问题呢?参考:http://blog.csdn.net/zdw890412/article/details/7360354我们首先获取旋转角度,根据不同的角度进行相应的旋转,如果旋转角度为0,则不旋转,这样,再次修改
getBitmap()方法,加入判断部分:
[code] Bitmap bm = null; try { ExifInterface exifInterface = new ExifInterface(path); int result = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); int rotate = 0; switch (result) { case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; default: break; } BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.RGB_565; options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); //... //压缩代码略 //... options.inJustDecodeBounds = false; bm = BitmapFactory.decodeFile(path, options); if (rotate > 0) { Matrix matrix = new Matrix(); matrix.setRotate(rotate, (float) options.outWidth / 2, (float) options.outHeight / 2); Bitmap rotateBm = Bitmap.createBitmap(bm, 0, 0, options.outWidth, options.outHeight, matrix, true); if(rotateBm !=null){ bm.recycle(); bm=rotateBm; } } return bm;
至此基本上大功告成。在HTC one 801e 手机上测试,发现根本获取不了Bitmap对象,返回空指针错误。
Android系统兼容性考虑
测试了很多机型,红米2A,三星Note3,魅族MX4,都是没有问题的,唯独用到HTC one时就崩溃了,返回空指针错误。HTC还真是傲娇。。怀疑是系统没有找到图片文件,我们知道调用系统相册将返回Uri数据,我们获取图片需要图片的路径,在腾讯优图的测试源码中, 提供了
uri2Path(Uri uri)方法,用来获取图片路径,通过打印发现HTC one 801e返回的
image/jpeg这个是Uri中的一个字段,但是到了Android的高版本以后,Uri的结构发生了一些变化,所以用老方法获取的Uri的位置得到的字段向下兼容,到了高版本就不行了,参考:http://blog.csdn.net/wblyuyang/article/details/45223813
重写
uri2Path(Uri uri)方法:
[code]@SuppressLint("NewApi") public String uri2Path(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(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; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } return null; } public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri .getAuthority()); } public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri .getAuthority()); } public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri .getAuthority()); }
OK,这次可以开心的听听音乐,谢谢博客了。在我所拥有的的测试条件下(红米2A,魅族MX4,三星Note3,HTC one 801e),皆可以完成腾讯优图API的正确接入。
总结
由于这次使用腾讯优图的API接入开发,不仅仅考虑自己的测试,还需要考虑APP的兼容性问题,主要考虑以下几点:不同机型自拍保存图片方向(与不同厂商摄像头调教有关)
高低版本Android系统的兼容性问题
不得不说,现在Android开发很多东西都特别混乱,增加了开发难度。
相关文章推荐
- Android动画_基本
- 一张图让你了解安卓事件处理流程的走向
- android事件分发、拦截、处理(未完)
- android 程序防止被360或者系统终止
- Android Studio Unable to execute DX
- Android 自定义的Dialog
- Android笔记:获取url或uri字符串中的参数值
- android单元测试
- Android通过代码模拟物理、屏幕点击事件
- Android开发之Canvas rotate方法释疑
- Android Support v4、v7、v13的含义是什么?
- Android中设置控件可见与不可见详解
- Android通用适配器
- Android 开发之接口回调
- android studio sonatype nexus aar
- Android模拟产生事件
- Android 日历CalendarProvider
- android项目设备管理器
- Android 监听数据变化比较合理的写法总结
- Android Material Design:滑动指示选项卡android.support.design.widget.TabLayout的简单使用