用户可选择拍照识别或者上传相册内图片,实现对照片中垃圾的识别。
前端上传图片到后端,调用阿里云垃圾识别api,返回数据给前端呈现
<template>
<view>
<camera device-position="back" flash="auto" @error="error" style="width: 100%; height: 1000upx;">
<cover-image src="../../static/img/scan-frame/scan-img.png" class="scan-img">cover-image>
camera>
<view class="scan-text"><text>请将想识别的垃圾放置白色框内text>view>
<view style="margin-left: 611rpx;margin-top: 55rpx;">
<image src="../../static/img/garbage/photo.png" style="width: 100rpx;height: 80rpx;" @click="takeAlbum">
image>
<view style="margin-left: 19rpx;">
<text style="color:#678D5D">相册text>
view>
view>
<view class="uni-button-group">
<button class="uni-button" @click="takePhoto" :styles="{'borderColor':'#678D5D'}">确定button>
view>
<orange-fullloading :loadicon="loadicon" text="识别中,请稍等" :loadshow="loadshow">orange-fullloading>
<orange-fullloading :loadicon="erricon" text="抱歉未能识别该物品" :loadshow="errshow">orange-fullloading>
view>
template>
<script>
const app = getApp()
export default {
data() {
return {
loadicon: '/static/img/garbage/xiaow.png',
erricon: '/static/img/garbage/xiaoerr.png',
src: "",
loadshow: false,
errshow: false,
garbageInfo: {},
header: {
'app-id': uni.getAccountInfoSync().miniProgram.appId,
'third-session': getApp().globalData.thirdSession != null ? getApp().globalData
.thirdSession : ''
},
path: app.globalData.config.basePath + '/weixin/api/ma/classify'
}
},
onShow() {
this.loadshow = false
this.errshow = false
//app.initPage().then((res) => {});
},
onLoad() {
this.loadshow = false
this.errshow = false
app.initPage().then((res) => {});
},
methods: {
//拍照上传
takePhoto() {
const ctx = uni.createCameraContext();
let that = this;
ctx.takePhoto({
quality: 'high',
success: (res) => {
console.log(res)
that.src = res.tempImagePath
console.log(that.src)
console.log(that.path)
//上传图片
that.loadshow = true
uni.uploadFile({
url: that.path, //图片上传接口
filePath: that.src,
name: 'file',
header: that.header,
success: (res) => {
console.log(result)
//that.garbageInfo = result.data[0]
//失败处理
let result = JSON.parse(res.data)
console.log(result)
if (result.code == 500 || result.data[0].category == "非生活垃圾" ||
result.data[0].rubbishScore == 0.0 || result.data[0]
.categoryScore == 0.0) {
that.loadshow = false
that.errshow = true
setTimeout(function() {
that.errshow = false
//跳转回页面
uni.redirectTo({
url: '/pages/identify/scan-frame'
});
}, 4000);
} else {
that.garbageInfo = result.data[0]
uni.navigateTo({
url: './detail?garbageInfo=' + encodeURIComponent(
JSON
.stringify(that.garbageInfo)) +
'&src=' + that.src
})
}
},
fail(err) {
console.log(err)
uni.showToast({
icon: 'error',
title: '抱歉未能识别该物品',
duration: 2000
})
}
});
//有路径
//返回调用页面并把图片URL传递过去
// let pages = getCurrentPages();
// let prevPage = pages[pages.length - 2];
// prevPage.setData({
// "image": that.src,
// })
// uni.navigateBack();
/* 调用页面获取图片URL方法 */
/* let pages = getCurrentPages();
let currPage = pages[pages.length-1];
if(typeof(currPage.data.image) != undefined && currPage.data.image != null){
console.log('获取图片:', currPage.data.image)
} */
}
});
},
error(e) {
console.log(e.detail);
},
//相册选择图片 一张
takeAlbum() {
let that = this;
that.loadshow = true
uni.chooseImage({
count: 1,
sourceType: ['album'], //从相册中获取
success: function(res) {
that.loadshow = true
console.log(res)
that.src = res.tempFilePaths[0]
// uni.showLoading({title: '加载中',mask:true})
console.log(that.src)
//上传图片
uni.uploadFile({
url: that.path, //图片上传接口
filePath: that.src,
name: 'file',
header: that.header,
success: (res) => {
console.log(res)
//返回的垃圾识别信息
let result = JSON.parse(res.data)
console.log(result)
if (result.code == 500 || result.data[0].category == "非生活垃圾" ||
result.data[0].rubbishScore == 0.0 || result.data[0]
.categoryScore == 0.0) {
that.loadshow = false
that.errshow = true
setTimeout(function() {
that.errshow = false
//跳转回页面
uni.redirectTo({
url: '/pages/identify/scan-frame'
});
}, 4000);
} else {
that.garbageInfo = result.data[0]
uni.navigateTo({
url: './detail?garbageInfo=' + encodeURIComponent(
JSON
.stringify(that.garbageInfo)) +
'&src=' + that.src
})
}
},
fail(err) {
console.log(err)
uni.showToast({
icon: 'error',
title: '抱歉未能识别该物品',
duration: 2000
})
}
});
uni.hideLoading()
},
fail: function(err) {
that.loadshow = false
uni.showToast({
icon: 'error',
title: '图片上传错误',
duration: 2000
})
}
});
}
}
}
script>
<style>
.scan-img {
opacity: 0.4;
width: 100%;
height: 1000upx;
}
.scan-text {
font-size: 16px;
text-align: center;
line-height: 60rpx;
font-weight: 700;
color: #678D5D;
}
.uni-button-group {
/* margin-top: 50px; */
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
margin-top: -77rpx;;
}
.uni-button {
width: 287rpx;
padding: 12px 20px;
font-size: 43rpx;
border-radius: 12px;
line-height: 1;
margin: 0;
background-color: #678D5D;
color: white;
}
style>
data() {
return {
//加载图片
loadicon: '/static/img/garbage/xiaow.png',
//加载失败图片
erricon: '/static/img/garbage/xiaoerr.png',
src: "",
//加载中是否显示
loadshow: false,
//出现错误是否显示
errshow: false,
//后端返回的识别出的垃圾信息
garbageInfo: {},
//请求头
header: {
'app-id': uni.getAccountInfoSync().miniProgram.appId,
'third-session': getApp().globalData.thirdSession != null ? getApp().globalData.thirdSession: ''
},
//上传接口
path: app.globalData.config.basePath + '/weixin/api/ma/classify'
}
},
takePhoto() {
const ctx = uni.createCameraContext();
let that = this;
ctx.takePhoto({
quality: 'high',
success: (res) = >{
console.log(res) that.src = res.tempImagePath console.log(that.src) console.log(that.path)
//上传图片
that.loadshow = true uni.uploadFile({
url: that.path,
//图片上传接口
filePath: that.src,
name: 'file',
header: that.header,
success: (res) = >{
console.log(result)
//that.garbageInfo = result.data[0]
//失败处理
let result = JSON.parse(res.data) console.log(result) if (result.code == 500 || result.data[0].category == "非生活垃圾" || result.data[0].rubbishScore == 0.0 || result.data[0].categoryScore == 0.0) {
that.loadshow = false that.errshow = true setTimeout(function() {
that.errshow = false
//跳转回页面
uni.redirectTo({
url: '/pages/identify/scan-frame'
});
},
4000);
} else {
that.garbageInfo = result.data[0] uni.navigateTo({
url: './detail?garbageInfo=' + encodeURIComponent(JSON.stringify(that.garbageInfo)) + '&src=' + that.src
})
}
},
fail(err) {
console.log(err) uni.showToast({
icon: 'error',
title: '抱歉未能识别该物品',
duration: 2000
})
}
});
//相册选择图片 一张
takeAlbum() {
let that = this;
that.loadshow = true uni.chooseImage({
//最大选取数量
count: 1,
sourceType: ['album'],
//从相册中获取
success: function(res) {
that.loadshow = true console.log(res)
//获取第一张图片src
that.src = res.tempFilePaths[0]
// uni.showLoading({title: '加载中',mask:true})
console.log(that.src)
//上传图片
uni.uploadFile({
url: that.path,
//图片上传接口
filePath: that.src,
name: 'file',
header: that.header,
success: (res) = >{
console.log(res)
//返回的垃圾识别信息
let result = JSON.parse(res.data)
//失败处理
if (result.code == 500 || result.data[0].category == "非生活垃圾" || result.data[0].rubbishScore == 0.0 || result.data[0].categoryScore == 0.0) {
that.loadshow = false that.errshow = true setTimeout(function() {
that.errshow = false
//跳转回页面
uni.redirectTo({
url: '/pages/identify/scan-frame'
});
},
4000);
} else {
that.garbageInfo = result.data[0] uni.navigateTo({
url: './detail?garbageInfo=' + encodeURIComponent(JSON.stringify(that.garbageInfo)) + '&src=' + that.src
})
}
},
fail(err) {
console.log(err) uni.showToast({
icon: 'error',
title: '抱歉未能识别该物品',
duration: 2000
})
}
});
uni.hideLoading()
},
//选择失败处理
fail: function(err) {
that.loadshow = false uni.showToast({
icon: 'error',
title: '请选择图片',
duration: 2000
})
}
});
package com.garbage.web.api;
import com.alibaba.fastjson.JSONArray;
import com.aliyun.imagerecog20190930.models.ClassifyingRubbishRequest;
import com.aliyun.imagerecog20190930.models.ClassifyingRubbishResponse;
import com.garbage.common.core.domain.AjaxResult;
import com.garbage.common.utils.ClassifyingRubbish.ClassifyingRubbish;
import com.garbage.mall.service.OssService;
import com.sun.xml.internal.ws.client.ClientTransportException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* 垃圾分类识别
*
* @author SY
* @date 2022-04-16 15:21:22
*/
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/weixin/api/ma/classify")
public class ClassifyingRubbishApi {
//上传oss工具
@Autowired
private OssService ossService;// AccessKey
private static String accessKey = your accessKey;
// AccessKeySecret
private static String accessKeySecret = your accessKeySecret;
@PostMapping
public AjaxResult classify(@PathParam(value = "file") MultipartFile file) {
try {
//上传到云桶
String url = ossService.uploadFile(file);
//创建代理
log.info("创建代理");
com.aliyun.imagerecog20190930.Client client = ClassifyingRubbish.createClient(accessKey, accessKeySecret);
ClassifyingRubbishRequest classifyingRubbishRequest = new ClassifyingRubbishRequest().setImageURL(url);
log.info("获取结果");
ClassifyingRubbishResponse resp = client.classifyingRubbish(classifyingRubbishRequest);
log.info(resp.toMap().toString());
System.out.println(resp.toMap());
log.info("创建代理oss");
//打印结果
log.info(client.classifyingRubbish(classifyingRubbishRequest).getBody().getData().toString());
//获取结果
log.info("获取返回值");
List list = client.classifyingRubbish(classifyingRubbishRequest).getBody().getData().getElements();
JSONArray jsonArray = (JSONArray) JSONArray.toJSON(list);
return AjaxResult.success(list);
} catch (ClientTransportException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return AjaxResult.error();
}
}
<dependency>
<groupId>com.aliyun.ossgroupId>
<artifactId>aliyun-sdk-ossartifactId>
<version>3.1.0version>
dependency>
<dependency>
<groupId>joda-timegroupId>
<artifactId>joda-timeartifactId>
<version>2.10.1version>
dependency>
# 阿里云oss配置
aliyun:
oss:
file:
endpoint: your endpoint
keyid: your key
keysecret: your secret
bucketname: your bucketname
package com.garbage.mall.util;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 常量类,读取配置文件application.properties中的配置
*/
@Component
//@PropertySource("classpath:application.properties")
//InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。
public class ConstantPropertiesUtils implements InitializingBean {
//从yml文件中读取配置
@Value("${aliyun.oss.file.endpoint}")
private String endpoint;
@Value("${aliyun.oss.file.keyid}")
private String keyId;
@Value("${aliyun.oss.file.keysecret}")
private String keySecret;
@Value("${aliyun.oss.file.bucketname}")
private String bucketName;
public static String END_POINT;
public static String ACCESS_KEY_ID;
public static String ACCESS_KEY_SECRET;
public static String BUCKET_NAME;
//@Value不能在static 字段上使用
//在初始化bean的时候为静态变量赋值
@Override
public void afterPropertiesSet() throws Exception {
END_POINT = endpoint;
ACCESS_KEY_ID = keyId;
ACCESS_KEY_SECRET = keySecret;
BUCKET_NAME = bucketName;
}
}
public interface OssService {
//上传到oss
String uploadFile(MultipartFile file);
}
@Service
public class OssServiceImpl implements OssService {
//上传图片到oss
@Override
public String uploadFile(MultipartFile file) {
// 工具类获取值
String endpoint = ConstantPropertiesUtils.END_POINT;
String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;
String bucketName = ConstantPropertiesUtils.BUCKET_NAME;
try {
// 创建OSS实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
//获取上传文件输入流
InputStream inputStream = file.getInputStream();
//获取文件名称
String fileName = file.getOriginalFilename();
//1 在文件名称里面添加随机唯一的值
String uuid = UUID.randomUUID().toString().replaceAll("-","");
fileName = uuid + fileName;
//2 把文件按照日期进行分类
//获取当前日期
String datePath = new DateTime().toString("yyyy/MM/dd");
//拼接
fileName = datePath+"/"+fileName;
//调用oss方法实现上传
//第一个参数 Bucket名称
//第二个参数 上传到oss文件路径和文件名称 aa/bb/1.jpg
//第三个参数 上传文件输入流
ossClient.putObject(bucketName,fileName,inputStream);
// 关闭OSSClient
ossClient.shutdown();
//把上传之后文件路径返回
//需要把上传到阿里云oss路径手动拼接出来
String url = "https://"+bucketName+"."+endpoint+"/"+fileName;
return url;
}catch(Exception e) {
e.printStackTrace();
return null; }
}
/**
* 使用AK&SK初始化账号Client
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/public static com.aliyun.imagerecog20190930.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
Config config = new Config()
// 您的AccessKey ID
.setAccessKeyId(accessKeyId)
// 您的AccessKey Secret
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = "imagerecog.cn-shanghai.aliyuncs.com";
//返回创建好的识别类
return new com.aliyun.imagerecog20190930.Client(config);
}