注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

罔少年

QQ 332256483

 
 
 

日志

 
 

webView长按识别二维码  

2017-02-15 10:25:14|  分类: android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

前言

        微信和支付宝把二维码用遍了大江南北,几乎各种应用中都变成标配了。类似微信中,打开一个网页,长按就能识别二维码,到底如何实现   

        QQ截图20170215095412.png

技术实现

        1、长按网页二维码图片,获取图片地址 (getHitTestResult())

        2、根据图片地址获取二维码图片本身 (xUtils3)

        2、识别二维码图片,获取二维码内容 (Google的二维码识别Zxing)

    

1、长按网页,获取图片地址getHitTestResult()

        webView的getHitTestResult()函数可以获取内容网页的基本信息

        getType()获取选中目标的类型:图片、超链接、邮件、电话等

        getExtra()获取额外信息

webView.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
//获取网页上所点击内容的信息
WebView.HitTestResult result = ((WebView) v).getHitTestResult();
if (null != result) {
//获取类型
int type = result.getType();
//判断是否为图片,是获取图片地址
if (type == WebView.HitTestResult.IMAGE_TYPE || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
String imageUrl = result.getExtra();
//imageUrl = "http://res.wx.qq.com/a/wx_fed/weixin_portal/res/static/img/5_8wy9W.png"
//下载二维码图片到本机
getBitMap(imageUrl);
}
}
return false;
}
});
webView.loadUrl("http://weixin.qq.com/cgi-bin/readtemplate?uin=&stype=&promote=&fr=www.baidu.com&lang=zh_CN&ADTAG=&check=false&nav=download&t=weixin_download_list&loc=readtemplate,weixin,body,3");

2、下载图片

         上面获取到了图片的地址,然后就是下载图片,这里用了xUtils3的下载文件功能

RequestParams requestParams = new RequestParams(imageUrl);
x.http().get(requestParams, new Callback.CommonCallback<File>() {
@Override
public void onSuccess(File file) {
Log.i("下载成功-----",file.getAbsolutePath() + "");
//获取二维码识别结果
Result result = scannImage(file.getAbsolutePath());
if(result == null) {
Toast.makeText(MainActivity.this, "图片格式错误", Toast.LENGTH_SHORT).show();

}else {
//result = "http://weixin.qq.com/d";
Toast.makeText(MainActivity.this, result.toString() + "", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onError(Throwable throwable, boolean b) {}
@Override
public void onCancelled(CancelledException e) {}
@Override
public void onFinished() {}
});

3、识别二维码图片,获取二维码内容

         1、先将本地二维码图片转化成bitmap

         2、bitmap二维码图片识别

Hashtable<DecodeHintType, String> hintTypeStringHashtable = new Hashtable<DecodeHintType, String>();
//解析转换类型UTF-8
hintTypeStringHashtable.put(DecodeHintType.CHARACTER_SET, "utf-8");
//获取到待解析的图片
BitmapFactory.Options options = new BitmapFactory.Options();
//只返回bitmap的信息,不返回bitmap本身
options.inJustDecodeBounds = true;
//inJustDecodeBounds = true bitmap = null;只返回bitmap基本信息
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
//设置二维码变成为400像素,正方形
int sampleSize = (int) (options.outHeight / (float) 400);
if (sampleSize <= 0) {
sampleSize = 1;
}
options.inSampleSize = sampleSize;
//返回缩放后的bitmap
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(imagePath, options);
//-------------------------------------------------------------------------------------------------------------------
//新建一个RGBLuminanceSource对象,将bitmap图片传给此对象
RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(bitmap);
//将图片转换成二进制图片
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(rgbLuminanceSource));
//初始化解析对象
QRCodeReader reader = new QRCodeReader();
try {
//返回解析结果
return reader.decode(binaryBitmap, hintTypeStringHashtable);
} catch (Exception e) {
// TODO: handle exception
}

项目结构及完整代码

        QQ截图20170215100524.png         


        1、引入二维码识别zxing及图片下载库xUtils3    

    compile 'com.google.zxing:core:3.2.1'
compile 'org.xutils:xutils:3.3.40'

        2、新建一个Application,初始化xUtils3库

public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//初始化xUtils3
x.Ext.init(this);
}
}   

        3、创建图片像素组类LuminanceSource    

import android.graphics.Bitmap;
import com.google.zxing.LuminanceSource;
/**
* Created by jiemiao.zhang on 2017-2-15.
*/
public class RGBLuminanceSource extends LuminanceSource {
private byte bitmapPixels[];
protected RGBLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
//获取图片像素组内容
int[] data = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight());
//int数组转换为byte数组
for (int i=0; i < data.length; i++) {
bitmapPixels[i] = (byte)data[i];
}
}
@Override
public byte[] getRow(int y, byte[] row) {
// 这里要得到指定行的像素数据
System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth());
return row;
}
@Override
public byte[] getMatrix() {
//返回生成好的像素数据
return bitmapPixels;
}
}

        4、MainActivity及activity_main.xml(里面就一个webView不写了)

public class MainActivity extends Activity {
private WebView webView;
private WebSettings mWebSettings;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("长按扫描二维码");
webView = (WebView) this.findViewById(R.id.webView1);
mWebSettings = webView.getSettings();
mWebSettings.setJavaScriptEnabled(true);
mWebSettings.setSupportZoom(true);
mWebSettings.setBuiltInZoomControls(true);
mWebSettings.setUseWideViewPort(true);
mWebSettings.setLoadWithOverviewMode(true);
webView.setWebViewClient(new WebViewClient());
webView.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
//获取网页上所点击内容的信息
WebView.HitTestResult result = ((WebView) v).getHitTestResult();
if (null != result) {
//获取类型
int type = result.getType();
//判断是否为图片,是获取图片地址
if (type == WebView.HitTestResult.IMAGE_TYPE || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
String imageUrl = result.getExtra();
//imageUrl = "http://res.wx.qq.com/a/wx_fed/weixin_portal/res/static/img/5_8wy9W.png"
//下载二维码图片到本机
getBitMap(imageUrl);
}
}
return false;
}
});
webView.loadUrl("http://weixin.qq.com/cgi-bin/readtemplate?uin=&stype=&promote=&fr=www.baidu.com&lang=zh_CN&ADTAG=&check=false&nav=download&t=weixin_download_list&loc=readtemplate,weixin,body,3");
}

//下载网络二维码图片
private void getBitMap(String imageUrl) {
RequestParams requestParams = new RequestParams(imageUrl);
x.http().get(requestParams, new Callback.CommonCallback<File>() {
@Override
public void onSuccess(File file) {
Log.i("下载成功-----",file.getAbsolutePath() + "");
//获取二维码识别结果
Result result = scannImage(file.getAbsolutePath());
if(result == null) {
Toast.makeText(MainActivity.this, "图片格式错误", Toast.LENGTH_SHORT).show();
}else {
//result = "http://weixin.qq.com/d";
Toast.makeText(MainActivity.this, result.toString() + "", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onError(Throwable throwable, boolean b) {}
@Override
public void onCancelled(CancelledException e) {}
@Override
public void onFinished() {}
});
}

/**
* 1、根据imagePath将图片转化成bitmap
* 2、对bitmap图片进行二维码识别
* @param imagePath
* @return
*/
private Result scannImage(String imagePath) {
if(TextUtils.isEmpty(imagePath)) {
return null;
}
//------------------------------------------------------------------------------------------------------------
Hashtable<DecodeHintType, String> hintTypeStringHashtable = new Hashtable<DecodeHintType, String>();
//解析转换类型UTF-8
hintTypeStringHashtable.put(DecodeHintType.CHARACTER_SET, "utf-8");

//获取到待解析的图片
BitmapFactory.Options options = new BitmapFactory.Options();
//只返回bitmap的信息,不返回bitmap本身
options.inJustDecodeBounds = true;
//inJustDecodeBounds = true bitmap = null;只返回bitmap基本信息
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
//设置二维码变成为400像素,正方形
int sampleSize = (int) (options.outHeight / (float) 400);
if (sampleSize <= 0) {
sampleSize = 1;
}
options.inSampleSize = sampleSize;
//返回缩放后的bitmap
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(imagePath, options);
//-------------------------------------------------------------------------------------------------------------------
//新建一个RGBLuminanceSource对象,将bitmap图片传给此对象
RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(bitmap);
//将图片转换成二进制图片
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(rgbLuminanceSource));
//初始化解析对象
QRCodeReader reader = new QRCodeReader();
try {
//返回解析结果
return reader.decode(binaryBitmap, hintTypeStringHashtable);
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
}   

以上代码刚经过2017-02-15测试,源码下载附件    

   我是程序猿 文章底部

  评论这张
 
阅读(169)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017