一、效果演示:http://www.bhshare.cn/imgcode/demo.html
-
本地圖片識別
本地上傳識別.png -
網(wǎng)絡圖片識別
網(wǎng)絡圖片識別.png
二、免費api接口
接口地址:http://www.bhshare.cn/imgcode/
請求類型:post
數(shù)據(jù)格式:application/x-www-form-urlencoded
接口參數(shù):
| 參數(shù)名 | 類型 | 是否必需 | 備注 |
|---|---|---|---|
| token | String | 是 | 用戶標識(token 免費獲取:http://www.bhshare.cn/imgcode/gettoken) |
| type | String | 是 | 識別類型。”online“:網(wǎng)絡圖片識別,”local“:本地圖片上傳 |
| uri | String | 否 | 在線圖片網(wǎng)址或圖片base64編碼(含頭部信息),當type取online時生效 |
| file | file | 否 | 本地圖片文件,當type取local時生效 |
返回數(shù)據(jù):
數(shù)據(jù)格式:json
| 參數(shù)名 | 類型 | 備注 |
|---|---|---|
| code | int | 狀態(tài)碼。200:識別成功,其他:識別失敗 |
| msg | String | 錯誤提示信息。當code不等于200時才有意義 |
| data | String | 識別結(jié)果 |
- python實現(xiàn)
# -*- coding: utf-8 -*-
# @Date : 2021/10/03
# @Author : 薄荷你玩
# @Website :http://www.bhshare.cn
import json
import requests
TOKEN = 'free' # token 獲取:http://www.bhshare.cn/imgcode/gettoken
URL = 'http://www.bhshare.cn/imgcode/' # 接口地址
def imgcode_online(imgurl):
"""
在線圖片識別
:param imgurl: 在線圖片網(wǎng)址 / 圖片base64編碼(包含頭部信息)
:return: 識別結(jié)果
"""
data = {
'token': TOKEN,
'type': 'online',
'uri': imgurl
}
response = requests.post(URL, data=data)
print(response.text)
result = json.loads(response.text)
if result['code'] == 200:
print(result['data'])
return result['data']
else:
print(result['msg'])
return 'error'
def imgcode_local(imgpath):
"""
本地圖片識別
:param imgpath: 本地圖片路徑
:return: 識別結(jié)果
"""
data = {
'token': TOKEN,
'type': 'local'
}
# binary上傳文件
files = {'file': open(imgpath, 'rb')}
response = requests.post(URL, files=files, data=data)
print(response.text)
result = json.loads(response.text)
if result['code'] == 200:
print(result['data'])
return result['data']
else:
print(result['msg'])
return 'error'
if __name__ == '__main__':
imgcode_online('http://www.bhshare.cn/test.png')
imgcode_local('img/test.png')
# 輸出樣例:
# {'code': 200, 'msg': 'ok', 'data': '74689'}
# 74689
- Java實現(xiàn)
/**
* @author 薄荷你玩
* @date 2021/10/04
* @Website http://www.bhshare.cn
*/
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Map.Entry;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
public class ImgcodeUtil {
private static final String URL = "http://www.bhshare.cn/imgcode/"; //接口地址
private static final String TOKEN = "free"; // token 獲?。篽ttp://www.bhshare.cn/imgcode/gettoken
private final static String BOUNDARY = UUID.randomUUID().toString().toLowerCase().replaceAll("-", "");// 邊界標識
private final static String PREFIX = "--";// 必須存在
private final static String LINE_END = "\r\n";
/**
* 網(wǎng)絡圖片識別
*
* @param imgUrl 圖片網(wǎng)址/圖片base64編碼
* @return 服務器返回結(jié)果(json格式)
*/
private static String imgcode_online(String imgUrl) {
String BOUNDARY = UUID.randomUUID().toString(); // 文件邊界隨機生成
HttpURLConnection con = null;
BufferedReader buffer = null;
StringBuffer resultBuffer = null;
try {
URL url = new URL(URL);
//得到連接對象
con = (HttpURLConnection) url.openConnection();
//設置請求類型
con.setRequestMethod("POST");
//設置請求需要返回的數(shù)據(jù)類型和字符集類型
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//允許寫出
con.setDoOutput(true);
//允許讀入
con.setDoInput(true);
//不使用緩存
con.setUseCaches(false);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
String content = "token=" + TOKEN;
content += "&type=online";
content += "&uri=" + URLEncoder.encode(imgUrl);
// DataOutputStream.writeBytes將字符串中的16位的unicode字符以8位的字符形式寫到流里面
out.writeBytes(content);
out.flush();
out.close();
//得到響應碼
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
//得到響應流
InputStream inputStream = con.getInputStream();
//將響應流轉(zhuǎn)換成字符串
resultBuffer = new StringBuffer();
String line;
buffer = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
while ((line = buffer.readLine()) != null) {
resultBuffer.append(line);
}
return resultBuffer.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 本地圖片上傳
*
* @param path 圖片路徑
* @return 返回數(shù)據(jù)(json)
*/
public static String imgcode_local(String path) throws Exception {
HttpURLConnection conn = null;
InputStream input = null;
OutputStream os = null;
BufferedReader br = null;
StringBuffer buffer = null;
try {
URL url = new URL(URL);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(1000 * 10);
conn.setReadTimeout(1000 * 10);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
conn.connect();
// 往服務器端寫內(nèi)容 也就是發(fā)起http請求需要帶的參數(shù)
os = new DataOutputStream(conn.getOutputStream());
// 請求參數(shù)部分
Map requestText = new HashMap();
requestText.put("token", TOKEN);
requestText.put("type", "local");
writeParams(requestText, os);
// 請求上傳文件部分
writeFile(path, os);
// 請求結(jié)束標志
String endTarget = PREFIX + BOUNDARY + PREFIX + LINE_END;
os.write(endTarget.getBytes());
os.flush();
// 讀取服務器端返回的內(nèi)容
if (conn.getResponseCode() == 200) {
input = conn.getInputStream();
} else {
input = conn.getErrorStream();
}
br = new BufferedReader(new InputStreamReader(input, "UTF-8"));
buffer = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line);
}
} catch (Exception e) {
throw new Exception(e);
} finally {
try {
if (conn != null) {
conn.disconnect();
conn = null;
}
if (os != null) {
os.close();
os = null;
}
if (br != null) {
br.close();
br = null;
}
} catch (IOException ex) {
throw new Exception(ex);
}
}
return buffer.toString();
}
/**
* 對post參數(shù)進行編碼處理并寫入數(shù)據(jù)流中
*
* @throws Exception
* @throws IOException
*/
private static void writeParams(Map requestText, OutputStream os) throws Exception {
try {
StringBuilder requestParams = new StringBuilder();
Set set = requestText.entrySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Entry entry = (Entry) it.next();
requestParams.append(PREFIX).append(BOUNDARY).append(LINE_END);
requestParams.append("Content-Disposition: form-data; name=\"")
.append(entry.getKey()).append("\"").append(LINE_END);
requestParams.append("Content-Type: text/plain; charset=utf-8")
.append(LINE_END);
requestParams.append("Content-Transfer-Encoding: 8bit").append(
LINE_END);
requestParams.append(LINE_END);// 參數(shù)頭設置完以后需要兩個換行,然后才是參數(shù)內(nèi)容
requestParams.append(entry.getValue());
requestParams.append(LINE_END);
}
os.write(requestParams.toString().getBytes());
os.flush();
} catch (Exception e) {
throw new Exception(e);
}
}
/**
* 對post上傳的文件進行編碼處理并寫入數(shù)據(jù)流中
*
* @throws IOException
* @path 文件路徑
*/
private static void writeFile(String path, OutputStream os) throws Exception {
try {
InputStream is = null;
File file = new File(path);
StringBuilder requestParams = new StringBuilder();
requestParams.append(PREFIX).append(BOUNDARY).append(LINE_END);
requestParams.append("Content-Disposition: form-data; name=\"")
.append("file").append("\"; filename=\"")
.append(file.getName()).append("\"")
.append(LINE_END);
requestParams.append("Content-Type:")
.append(getContentType(file))
.append(LINE_END);
requestParams.append("Content-Transfer-Encoding: 8bit").append(
LINE_END);
requestParams.append(LINE_END);// 參數(shù)頭設置完以后需要兩個換行,然后才是參數(shù)內(nèi)容
os.write(requestParams.toString().getBytes());
is = new FileInputStream(file);
byte[] buffer = new byte[1024 * 1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.write(LINE_END.getBytes());
os.flush();
} catch (Exception e) {
throw new Exception(e);
}
}
/**
* 獲取ContentType
*/
public static String getContentType(File file) throws Exception {
String streamContentType = "application/octet-stream";
String imageContentType = "";
ImageInputStream image = null;
try {
image = ImageIO.createImageInputStream(file);
if (image == null) {
return streamContentType;
}
Iterator it = ImageIO.getImageReaders(image);
if (it.hasNext()) {
imageContentType = "image/png";
return imageContentType;
}
} catch (IOException e) {
throw new Exception(e);
} finally {
try {
if (image != null) {
image.close();
}
} catch (IOException e) {
throw new Exception(e);
}
}
return streamContentType;
}
public static void main(String[] args) throws Exception {
String path = "E:\\NLP_study\\imgcode\\img\\test.png";
System.out.println(imgcode_local(path));
System.out.println(imgcode_online("http://www.bhshare.cn/test.png"));
// 輸出:
// {"code":200,"msg":"ok","times":93,"data":"yemm"}
// {"code":200,"msg":"ok","times":92,"data":"74689"}
}
}
-
HTML/JavaScript實現(xiàn)
網(wǎng)絡圖片識別:
<!--網(wǎng)絡圖片識別/html-->
<input type="text" name="uri" id="uri" placeholder="請輸入驗證碼圖片網(wǎng)址" />
<input type="button" onclick="imgcode()" value="識別" />
<input name="token" id="token" value="free" type="hidden">
<input name="type" value="online" type="hidden">
<p>識別結(jié)果:<span id="resultCode" style="color:red;">請稍后...</span></p>
// 網(wǎng)絡圖片識別/js
function imgcode() {
if ($("#uri").val() == "") {
alert("網(wǎng)址不能為空");
return;
}
$.ajax({
type: "post",
url: "http://www.bhshare.cn/imgcode/",
data: {
token: $("#token").val(),
uri: $("#uri").val(),
type: "online"
},
dataType: "json",
success: function (data) {
console.log(data);
if (data.code > 0) {
$("#resultCode").text(data.data);
} else {
$("#resultCode").text(data.msg);
}
},
error: function (result) {
console.log(result);
$("#resultCode").text(JSON.stringify(result));
alert("系統(tǒng)繁忙,請稍后再試!");
}
});
}
本地圖片上傳:
<!--本地圖片上傳/html-->
<form encType="multipart/form-data" method="post" id="selPicture">
<input type="file" accept="image/*" name="selPicture" id="file" />
<input type="button" name="upload" onclick="sendimg()" id="upload" value="識別" />
<input name="token" value="free" type="hidden">
<input name="type" value="local" type="hidden">
</form>
<p>識別結(jié)果:<span id="resultCode" style="color:red;">請稍后...</span></p>
// 本地圖片上傳/js
function sendimg() {
var $file1 = $("input[name='selPicture']").val();//用戶文件內(nèi)容(文件)
// 判斷文件是否為空
if ($file1 == "") {
alert("請選擇上傳的目標文件! ")
return false;
}
//判斷文件大小
var size1 = $("input[name='selPicture']")[0].files[0].size;
if (size1 > 5242880) {
alert("上傳文件不能大于5M!");
return false;
}
boo1 = true;
var type = "file";
var formData = new FormData($("#selPicture")[0]);//這里需要實例化一個FormData來進行文件上傳
$.ajax({
type: "post",
url: "http://www.bhshare.cn/imgcode/",
data: formData,
processData: false,
contentType: false,
dataType: "json",
success: function (data) {
console.log(data);
if (data.code == 200) {
$("#resultCode").text(data.data);
} else {
$("#resultCode").text(data.msg);
}
},
error: function (result) {
console.log(result);
$("#resultCode").text(JSON.stringify(result));
alert("系統(tǒng)繁忙,請稍后再試!");
}
});
}

