Zxing图片识别 从相册选二维码图片解析总结
2014-05-03 10:06
323 查看
Zxing图片识别从相册选取二维码图片进行解析总结
在Zxing扫描识别和图片识别的解析对象是相同的
本文分三个步骤:
1获取相册的照片
2解析二维码图片
3返回结果
在Activity中开启相册:
选中了照片后返回的数据在onActivityResult方法中获取
上面这段代码
<1>根据返回的照片信息获取图片的路径photo_path
<2>开启一个解析线程调用解析方法Resultresult=scanningImage(photo_path);将photo_path传进去
<3>对返回的解析的Result对象进行判断,获取字符串
<4>调用recode对result数据进行中文乱码处理(具体在步骤3中说明)
<5>这里我将result通过setResult();返回给了父Activity
<6>Utils.getPath(getApplicationContext(),data.getData());//将图片Uri转换成绝对路径
首先对result判断是否为空,如果为空就代表二维码不标准或者不是二维码图片
在子线程中使用Toast需要初始化looper
Result对象返回的就是二维码扫描的结果
调用recode(result.toString)方法进行中文乱码处理代码如下:
处理好之后将结果字符串返回给父Activity
对于图片识别有些事项需要注意..
二维码的图标需要保证图片尽量不倾斜拍照的时候最好保证手机与二维码水平
附图:
希望对您有用不足之处请指出谢谢
资源下载地址:http://download.csdn.net/detail/aaawqqq/7281577
在Zxing扫描识别和图片识别的解析对象是相同的
本文分三个步骤:
1获取相册的照片
2解析二维码图片
3返回结果
1)获取相册照片
google对4.4的uri做了点改动为了适配多种手机需要做一个判断版本在Activity中开启相册:
IntentinnerIntent=newIntent();//"android.intent.action.GET_CONTENT" if(Build.VERSION.SDK_INT<19){ innerIntent.setAction(Intent.ACTION_GET_CONTENT); }else{ innerIntent.setAction(Intent.ACTION_OPEN_DOCUMENT); } innerIntent.setType("image/*"); IntentwrapperIntent=Intent.createChooser(innerIntent,"选择二维码图片"); CaptureActivity.this .startActivityForResult(wrapperIntent,REQUEST_CODE);
选中了照片后返回的数据在onActivityResult方法中获取
@Override protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ super.onActivityResult(requestCode,resultCode,data); if(resultCode==RESULT_OK){ switch(requestCode){ caseREQUEST_CODE: String[]proj={MediaStore.Images.Media.DATA}; //获取选中图片的路径 Cursorcursor=getContentResolver().query(data.getData(), proj,null,null,null); if(cursor.moveToFirst()){ intcolumn_index=cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); photo_path=cursor.getString(column_index); if(photo_path==null){ photo_path=Utils.getPath(getApplicationContext(), data.getData()); Log.i("123pathUtils",photo_path); } Log.i("123path",photo_path); } cursor.close(); newThread(newRunnable(){ @Override publicvoidrun(){ Resultresult=scanningImage(photo_path); //Stringresult=decode(photo_path); if(result==null){ Looper.prepare(); Toast.makeText(getApplicationContext(),"图片格式有误",0) .show(); Looper.loop(); }else{ Log.i("123result",result.toString()); //Log.i("123result",result.getText()); //数据返回 Stringrecode=recode(result.toString()); Intentdata=newIntent(); data.putExtra("result",recode); setResult(300,data); finish(); } } }).start(); break; } } }
上面这段代码
<1>根据返回的照片信息获取图片的路径photo_path
<2>开启一个解析线程调用解析方法Resultresult=scanningImage(photo_path);将photo_path传进去
<3>对返回的解析的Result对象进行判断,获取字符串
<4>调用recode对result数据进行中文乱码处理(具体在步骤3中说明)
Stringrecode=recode(result.toString());
<5>这里我将result通过setResult();返回给了父Activity
<6>Utils.getPath(getApplicationContext(),data.getData());//将图片Uri转换成绝对路径
publicclassUtils{
publicstaticfinalbooleanisChineseCharacter(StringchineseStr){
char[]charArray=chineseStr.toCharArray();
for(inti=0;i<charArray.length;i++){
//是否是Unicode编码,除了"�"这个字符.这个字符要另外处理
if((charArray[i]>='\u0000'&&charArray[i]<'\uFFFD')
||((charArray[i]>'\uFFFD'&&charArray[i]<'\uFFFF'))){
continue;
}else{
returnfalse;
}
}
returntrue;
}
/**
*GetafilepathfromaUri.ThiswillgetthethepathforStorageAccess
*FrameworkDocuments,aswellasthe_datafieldfortheMediaStoreand
*otherfile-basedContentProviders.
*
*@paramcontext
*Thecontext.
*@paramuri
*TheUritoquery.
*@authorpaulburke
*/
publicstaticStringgetPath(finalContextcontext,finalUriuri){
finalbooleanisKitKat=Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT;
//DocumentProvider
if(isKitKat&&DocumentsContract.isDocumentUri(context,uri)){
//ExternalStorageProvider
if(isExternalStorageDocument(uri)){
finalStringdocId=DocumentsContract.getDocumentId(uri);
finalString[]split=docId.split(":");
finalStringtype=split[0];
if("primary".equalsIgnoreCase(type)){
returnEnvironment.getExternalStorageDirectory()+"/"
+split[1];
}
//TODOhandlenon-primaryvolumes
}
//DownloadsProvider
elseif(isDownloadsDocument(uri)){
finalStringid=DocumentsContract.getDocumentId(uri);
finalUricontentUri=ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
returngetDataColumn(context,contentUri,null,null);
}
//MediaProvider
elseif(isMediaDocument(uri)){
finalStringdocId=DocumentsContract.getDocumentId(uri);
finalString[]split=docId.split(":");
finalStringtype=split[0];
UricontentUri=null;
if("image".equals(type)){
contentUri=MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}elseif("video".equals(type)){
contentUri=MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
}elseif("audio".equals(type)){
contentUri=MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
finalStringselection="_id=?";
finalString[]selectionArgs=newString[]{split[1]};
returngetDataColumn(context,contentUri,selection,
selectionArgs);
}
}
//MediaStore(andgeneral)
elseif("content".equalsIgnoreCase(uri.getScheme())){
returngetDataColumn(context,uri,null,null);
}
//File
elseif("file".equalsIgnoreCase(uri.getScheme())){
returnuri.getPath();
}
returnnull;
}
/**
*GetthevalueofthedatacolumnforthisUri.Thisisusefulfor
*MediaStoreUris,andotherfile-basedContentProviders.
*
*@paramcontext
*Thecontext.
*@paramuri
*TheUritoquery.
*@paramselection
*(Optional)Filterusedinthequery.
*@paramselectionArgs
*(Optional)Selectionargumentsusedinthequery.
*@returnThevalueofthe_datacolumn,whichistypicallyafilepath.
*/
publicstaticStringgetDataColumn(Contextcontext,Uriuri,
Stringselection,String[]selectionArgs){
Cursorcursor=null;
finalStringcolumn="_data";
finalString[]projection={column};
try{
cursor=context.getContentResolver().query(uri,projection,
selection,selectionArgs,null);
if(cursor!=null&&cursor.moveToFirst()){
finalintcolumn_index=cursor.getColumnIndexOrThrow(column);
returncursor.getString(column_index);
}
}finally{
if(cursor!=null)
cursor.close();
}
returnnull;
}
/**
*@paramuri
*TheUritocheck.
*@returnWhethertheUriauthorityisExternalStorageProvider.
*/
publicstaticbooleanisExternalStorageDocument(Uriuri){
return"com.android.externalstorage.documents".equals(uri
.getAuthority());
}
/**
*@paramuri
*TheUritocheck.
*@returnWhethertheUriauthorityisDownloadsProvider.
*/
publicstaticbooleanisDownloadsDocument(Uriuri){
return"com.android.providers.downloads.documents".equals(uri
.getAuthority());
}
/**
*@paramuri
*TheUritocheck.
*@returnWhethertheUriauthorityisMediaProvider.
*/
publicstaticbooleanisMediaDocument(Uriuri){
return"com.android.providers.media.documents".equals(uri
.getAuthority());
}
}
2)解析二维码图片
protectedResultscanningImage(Stringpath){
if(TextUtils.isEmpty(path)){
returnnull;
}
//DecodeHintType和EncodeHintType
Hashtable<DecodeHintType,String>hints=newHashtable<DecodeHintType,String>();
hints.put(DecodeHintType.CHARACTER_SET,"utf-8");//设置二维码内容的编码
BitmapFactory.Optionsoptions=newBitmapFactory.Options();
options.inJustDecodeBounds=true;//先获取原大小
scanBitmap=BitmapFactory.decodeFile(path,options);
options.inJustDecodeBounds=false;//获取新的大小
intsampleSize=(int)(options.outHeight/(float)200);
if(sampleSize<=0)
sampleSize=1;
options.inSampleSize=sampleSize;
scanBitmap=BitmapFactory.decodeFile(path,options);
RGBLuminanceSourcesource=newRGBLuminanceSource(scanBitmap);
BinaryBitmapbitmap1=newBinaryBitmap(newHybridBinarizer(source));
QRCodeReaderreader=newQRCodeReader();
try{
returnreader.decode(bitmap1,hints);
}catch(NotFoundExceptione){
e.printStackTrace();
}catch(ChecksumExceptione){
e.printStackTrace();
}catch(FormatExceptione){
e.printStackTrace();
}
returnnull;
}
3)返回结果
首先对result判断是否为空,如果为空就代表二维码不标准或者不是二维码图片在子线程中使用Toast需要初始化looper
Resultresult=scanningImage(photo_path);
//Stringresult=decode(photo_path);
if(result==null){
Looper.prepare();
Toast.makeText(getApplicationContext(),"图片格式有误",0)
.show();
Looper.loop();
}else{
Log.i("123result",result.toString());
//Log.i("123result",result.getText());
//数据返回
Stringrecode=recode(result.toString());
Intentdata=newIntent();
data.putExtra("result",recode);
setResult(300,data);
finish();
}
Result对象返回的就是二维码扫描的结果
调用recode(result.toString)方法进行中文乱码处理代码如下:
privateStringrecode(Stringstr){
Stringformart="";
try{
booleanISO=Charset.forName("ISO-8859-1").newEncoder()
.canEncode(str);
if(ISO){
formart=newString(str.getBytes("ISO-8859-1"),"GB2312");
Log.i("1234ISO8859-1",formart);
}else{
formart=str;
Log.i("1234stringExtra",str);
}
}catch(UnsupportedEncodingExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
returnformart;
}
处理好之后将结果字符串返回给父Activity
对于图片识别有些事项需要注意..
二维码的图标需要保证图片尽量不倾斜拍照的时候最好保证手机与二维码水平
附图:
希望对您有用不足之处请指出谢谢
资源下载地址:
相关文章推荐
- js:对象的创建(为prototype做铺垫)
- ORACLE 创建表空间、用户、授权
- 并发管理器1——概念
- [c.y.j]spring redis utils
- VS2012 离线帮助文档帮错 指定的用于安装帮助内容的位置无效, 的处理办法
- 使用Visual Studio 2013 从头构建Web表单
- thinkphp 404页面设置
- Ubuntu常用命令大全
- windows系统文件夹下最多有多少个子文件
- c++开源库
- LNMMP架构的实现
- 关于SSH框架中的错误整理,遇到的问题都是前进的台阶
- LeetCode刷题笔录Single Number II
- 骨牌铺方格
- poj 1077 八数码(BFS+康托展开)
- 基于DM3730平台的gstreamer音视频传输调试
- RSA加密算法 实例讲解
- TextSlidingMenu上下滑动效果
- 自增++运算符的重载
- JBPM学习(四):执行流程实例