更新记录
1.2.5(2025-11-05)
下载此版本
OCR图片识别,传入图片文件或图片链接,识别图片内容
平台兼容性
uni-app(4.65)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
uni-app x(4.61)
| Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
| √ |
√ |
√ |
√ |
√ |
√ |
其他
介绍
本功能基于轻语API
轻语API提供一键生成二维码、OCR文字识别、文字转语音、随机图库、智能Ai助手、地理编码获取(逆地理编码,从内容中获取地址信息(含经纬度),从经纬度获取地址信息)等等API
<template>
<view class="container">
<!-- 图片上传区域 -->
<view class="upload-section">
<view class="section-title">上传图片文件:</view>
<view class="upload-area" @click="chooseImage">
<image v-if="imagePreview" :src="imagePreview" class="preview-image" mode="aspectFit"></image>
<view v-else class="upload-placeholder">
<text class="upload-icon">📷</text>
<text class="upload-text">点击选择图片</text>
</view>
</view>
<view v-if="imageFile" class="file-info">
<text class="file-name">已选择:{{ imageFile.name || '图片文件' }}</text>
<text class="remove-btn" @click.stop="removeImage">✕</text>
</view>
</view>
<!-- URL输入区域 -->
<view class="input-section">
<view class="section-title">或输入图片URL:</view>
<view class="tip-text">⚠️ 图片文件和URL二选一,如果都填写则优先使用图片文件</view>
<input v-model="imageUrl" class="input" placeholder="请输入图片URL地址" />
</view>
<!-- API Key -->
<view class="apikey-section">
<view class="section-title">API Key:</view>
<view class="apikey-tip">共用测试Key,当日额度用尽后次日重置,上线请用正式key</view>
<input v-model="apikey" class="input" placeholder="test_app_key_5555api.com" />
</view>
<!-- 查询按钮 -->
<view class="button-section">
<view class="btn btn-clear" @click="onClear">清空</view>
<!-- 等待进度条 -->
<view v-if="status==='loading'">
<image src="/static/icon_spinner.png" style="width: 68rpx;height: 68rpx;" class="rotating-element"></image>
</view>
<navigator v-else url="/pages/index/index" class="link-text">查看其他API</navigator>
<view class="btn btn-query" @click="onRecognize">识别</view>
</view>
<!-- 请求URL展示 -->
<view v-if="requestUrl" class="url-section">
<view class="section-title">请求URL(长按可复制):</view>
<view class="url-content" @longpress="copyUrl">{{ requestUrl }}</view>
</view>
<!-- 结果展示 -->
<view v-if="resultText" class="result-section">
<view class="section-title">识别结果(长按可复制结果内容):</view>
<view class="result-content" @longpress="copyResult">{{ resultText }}</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageFile: null,
imagePreview: '',
imageUrl: 'https://mp-4600ec1f-16af-433c-a045-130f8b08315f.cdn.bspapp.com/test/test3.png',
language: 'auto',
apikey: 'test_app_key_5555api.com', // 测试用的共享apikey,每日有限额
resultText: '',
requestUrl: '',
status: '',
languages: [
{ label: '精准中文(明确知道只有图片里中文)', value: 'ch' },
{ label: '智能识别', value: 'auto' },
]
}
},
methods: {
// 选择图片
chooseImage() {
let that = this;
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePath = res.tempFilePaths[0];
that.imagePreview = tempFilePath;
that.imageFile = {
path: tempFilePath,
name: tempFilePath.split('/').pop()
};
uni.showToast({
title: '图片已选择',
icon: 'success'
});
},
fail: (err) => {
console.error('选择图片失败:', err);
uni.showToast({
title: '选择图片失败',
icon: 'none'
});
}
});
},
// 移除图片
removeImage() {
this.imageFile = null;
this.imagePreview = '';
uni.showToast({
title: '已移除图片',
icon: 'success'
});
},
// 清空内容
onClear() {
this.imageFile = null;
this.imagePreview = '';
this.imageUrl = '';
this.language = 'ch';
this.resultText = '';
this.requestUrl = '';
},
// 长按复制URL
copyUrl() {
if(this.requestUrl) {
uni.setClipboardData({
data: this.requestUrl,
success: () => {
uni.showToast({
title: 'URL已复制',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
}
},
// 长按复制结果
copyResult() {
if(this.resultText) {
uni.setClipboardData({
data: this.resultText,
success: () => {
uni.showToast({
title: '结果已复制',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
}
},
// OCR识别
onRecognize() {
let that = this;
// 验证输入
if(!that.imageFile && !that.imageUrl) {
uni.showToast({
title: '请选择图片或输入图片URL',
icon: 'none'
});
return;
}
if(!that.apikey) {
uni.showToast({
title: '请输入API Key',
icon: 'none'
});
return;
}
that.status = 'loading';
that.resultText = '';
const baseUrl = 'https://5555api.com/data/api/ocrRecognize';
// 如果有图片文件,优先使用文件上传
if(that.imageFile) {
// 生成请求URL(文件上传时显示参数)
that.requestUrl = `${baseUrl}?language=${that.language}&apikey=${that.apikey}&file=[文件上传]`;
uni.uploadFile({
url: baseUrl,
filePath: that.imageFile.path,
name: 'file',
formData: {
language: that.language,
apikey: that.apikey
},
timeout: 30000,
success(res) {
that.status = '';
console.log('请求成功:', res);
try {
const data = JSON.parse(res.data);
that.resultText = JSON.stringify(data, null, 2);
} catch(e) {
that.resultText = res.data;
}
},
fail(err) {
that.status = '';
console.error('请求失败:', err);
that.resultText = "服务异常:" + (err.errMsg || '网络请求失败');
uni.showToast({
title: '请求失败',
icon: 'none'
});
}
});
} else {
// 使用URL方式
that.requestUrl = `${baseUrl}?url=${encodeURIComponent(that.imageUrl)}&language=${that.language}&apikey=${that.apikey}`;
uni.request({
method: 'POST',
url: baseUrl,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
data: {
url: that.imageUrl,
language: that.language,
apikey: that.apikey
},
timeout: 30000,
success(res) {
that.status = '';
console.log('请求成功:', res);
if(res.data) {
that.resultText = JSON.stringify(res.data, null, 2);
} else {
that.resultText = "识别成功,但未返回数据";
}
},
fail(err) {
that.status = '';
console.error('请求失败:', err);
that.resultText = "服务异常:" + (err.errMsg || '网络请求失败');
uni.showToast({
title: '请求失败',
icon: 'none'
});
}
});
}
}
}
}
</script>
<style scoped>
.container {
padding: 40rpx;
}
/* 上传区域 */
.upload-section {
margin-bottom: 30rpx;
}
.upload-area {
width: 100%;
height: 400rpx;
border: 2rpx dashed #12c212;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: #f9f9f9;
overflow: hidden;
}
.preview-image {
width: 100%;
height: 100%;
}
.upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.upload-icon {
font-size: 80rpx;
margin-bottom: 20rpx;
}
.upload-text {
font-size: 28rpx;
color: #999;
}
.file-info {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 15rpx;
padding: 15rpx 20rpx;
background-color: #e8f5e9;
border-radius: 10rpx;
}
.file-name {
flex: 1;
font-size: 24rpx;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.remove-btn {
margin-left: 20rpx;
padding: 5rpx 15rpx;
font-size: 28rpx;
color: #f44336;
font-weight: bold;
}
/* 输入区域 */
.input-section {
margin-bottom: 30rpx;
}
.section-title {
font-size: 28rpx;
color: #666;
margin-bottom: 15rpx;
font-weight: bold;
}
.tip-text {
font-size: 24rpx;
color: #ff9800;
margin-bottom: 15rpx;
line-height: 1.5;
}
.apikey-tip {
font-size: 24rpx;
color: #2196f3;
margin-bottom: 15rpx;
line-height: 1.5;
}
.input {
width: 100%;
height: 70rpx;
padding: 0 20rpx;
border: 2rpx solid #12c212;
border-radius: 10rpx;
font-size: 28rpx;
box-sizing: border-box;
}
/* 语言选择区域 */
.language-section {
margin-bottom: 30rpx;
}
.language-options {
display: flex;
flex-wrap: wrap;
gap: 15rpx;
}
.language-item {
padding: 15rpx 30rpx;
background-color: #f5f5f5;
border: 2rpx solid #e0e0e0;
border-radius: 10rpx;
font-size: 28rpx;
color: #333;
}
.language-item.active {
background-color: #12c212;
color: #fff;
border-color: #12c212;
}
/* API Key区域 */
.apikey-section {
margin-bottom: 30rpx;
}
/* 按钮区域 */
.button-section {
display: flex;
align-items: center;
justify-content: space-around;
margin-bottom: 40rpx;
}
.btn {
color: #fff;
border-radius: 12rpx;
font-size: 30rpx;
padding: 15rpx 40rpx;
}
.btn-clear {
background-color: #999;
}
.btn-query {
background-color: cornflowerblue;
}
.link-text {
font-size: 26rpx;
color: #999999;
text-align: center;
}
/* URL展示区域 */
.url-section {
margin-top: 20rpx;
}
.url-content {
padding: 20rpx;
background-color: #fff8e1;
border: 2rpx solid #ffa726;
border-radius: 10rpx;
font-size: 22rpx;
color: #e65100;
word-break: break-all;
line-height: 1.5;
}
/* 结果展示区域 */
.result-section {
margin-top: 20rpx;
}
.result-content {
padding: 20rpx;
background-color: #f9f9f9;
border: 2rpx solid #12c212;
border-radius: 10rpx;
font-size: 24rpx;
color: #333;
white-space: pre-wrap;
word-break: break-all;
max-height: 600rpx;
overflow-y: auto;
}
/* 加载动画 */
.rotating-element {
animation: rotateAnimation 2s linear infinite;
}
@keyframes rotateAnimation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>