Browse Source

文件上传,审核,压缩上传

master
qyhdd 4 years ago
parent
commit
df5a2c9553
  1. 7
      bnyer-services/bnyer-file/pom.xml
  2. 27
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/TikTokConfig.java
  3. 67
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java
  4. 15
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IFileService.java
  5. 11
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IQiniuService.java
  6. 1
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/ITikTokImage.java
  7. 71
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/FileServiceImpl.java
  8. 37
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/QiniuServiceImpl.java
  9. 47
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/TikTokImageServiceImpl.java
  10. 4
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/HttpUtils.java
  11. 134
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java
  12. 45
      bnyer-services/bnyer-file/src/main/java/com/bnyer/file/vo/TiktokImgVo.java
  13. 2
      bnyer-services/bnyer-file/src/main/resources/bootstrap.yml

7
bnyer-services/bnyer-file/pom.xml

@ -87,6 +87,13 @@
<artifactId>okhttp</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
<version>2.0.8</version>
</dependency>
</dependencies>
<build>

27
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/TikTokConfig.java

@ -0,0 +1,27 @@
package com.bnyer.file.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
/**
* @Author: qyh
* @Date: 2022-06-12-16:24
* @Description:
*/
@Configuration
@RefreshScope
@Getter
@Setter
public class TikTokConfig {
@Value("${tiktok.appId}")
private String appId;
@Value("${tiktok.secret}")
private String secret;
@Value("${tiktok.grant_type}")
private String grant_type;
}

67
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java

@ -1,8 +1,13 @@
package com.bnyer.file.controller;
import com.alibaba.fastjson.JSONObject;
import com.bnyer.common.core.domain.R;
import com.bnyer.file.service.IFileService;
import com.bnyer.file.service.IQiniuService;
import com.bnyer.file.service.ITikTokImage;
import com.bnyer.file.service.MinioService;
import com.bnyer.file.utils.ImgUtil;
import com.bnyer.file.vo.TiktokImgVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
@ -12,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -22,30 +28,65 @@ import java.util.List;
*/
@RestController
@Slf4j
public class SysFileController
{
public class SysFileController {
@Autowired
private MinioService minioService;
@Autowired
private IQiniuService qiniuService;
@Autowired
private ITikTokImage tikTokImage;
@Autowired
private IFileService fileService;
/**
* 批量上传图片
*/
@PostMapping("/uploadBatch")
public R<List<String>> uploadBatch(MultipartFile[] files)
{
try
{
public R<List<String>> uploadBatch(MultipartFile[] files) {
try {
List<String> list = new ArrayList<>();
for (MultipartFile file : files) {
String url = qiniuService.userUpload(file);
list.add(url);
}
// 上传并返回访问地址
return R.ok(list);
} catch (Exception e) {
log.error("上传文件失败", e);
return R.fail("上传文件失败");
}
}
/**
* 批量上传压缩图片
* @param files
* @return
* @throws IOException
*/
@PostMapping("/uploadBatchCompImg")
public R<List<String>> compression(MultipartFile[] files) throws IOException {
List<String> list = new ArrayList<>();
for (MultipartFile file : files) {
String url = minioService.uploadFile(file);
MultipartFile file1 = ImgUtil.commpressPicCycle(100, 0.5f, file);
System.out.println("sssss");
String url = qiniuService.userUpload(file1);
list.add(url);
}
// 上传并返回访问地址
return R.ok(list);
}
catch (Exception e)
{
/**
* 批量审核
*/
@PostMapping("/checkBatch")
public R<List<TiktokImgVo>> checkBatch(ArrayList<MultipartFile> files) {
try {
ArrayList<TiktokImgVo> list = fileService.checkImg(files);
// 上传并返回访问地址
return R.ok(list);
} catch (Exception e) {
log.error("上传文件失败", e);
return R.fail("上传文件失败");
}
@ -57,7 +98,13 @@ public class SysFileController
String url = null;
try {
//url = minioService.uploadFile(file);
url=qiniuService.userUpload(file);
// url=qiniuService.userUpload(file);
String imageString = ImgUtil.getImageString(file);
//System.out.println(imageString);
//JSONObject jsonObject = qiniuService.checkImageContent("data:application/octet-stream;base64," + imageString);
System.out.println("=================================");
//System.out.println(jsonObject);
tikTokImage.checkImageContent(file);
} catch (Exception e) {
log.error("文件上传失败,原因为:【{}】", e.getMessage());
return R.fail("文件上传失败!");

15
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IFileService.java

@ -0,0 +1,15 @@
package com.bnyer.file.service;
import com.bnyer.file.vo.TiktokImgVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
/**
* @Author: qyh
* @Date: 2022-06-16-11:03
* @Description:
*/
public interface IFileService {
ArrayList<TiktokImgVo> checkImg(ArrayList<MultipartFile> multipartFiles);
}

11
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IQiniuService.java

@ -1,9 +1,20 @@
package com.bnyer.file.service;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.ArrayList;
public interface IQiniuService {
String userUpload(MultipartFile file);
String checkImageContent(String imageUrl);
/**
* 检查图片格式
* @param multipartFiles
* @return
*/
ArrayList<MultipartFile> checkImageFormat(ArrayList<MultipartFile> multipartFiles);
}

1
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/ITikTokImage.java

@ -8,5 +8,6 @@ import org.springframework.web.multipart.MultipartFile;
* @Description:
*/
public interface ITikTokImage {
//抖音图片审核
Boolean checkImageContent(MultipartFile file);
}

71
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/FileServiceImpl.java

@ -0,0 +1,71 @@
package com.bnyer.file.service.impl;
import cn.hutool.core.img.Img;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bnyer.file.config.TikTokConfig;
import com.bnyer.file.service.IFileService;
import com.bnyer.file.service.IQiniuService;
import com.bnyer.file.service.ITikTokImage;
import com.bnyer.file.utils.HttpUtils;
import com.bnyer.file.utils.ImgUtil;
import com.bnyer.file.vo.TiktokImgVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.HashMap;
/**
* @Author: Yeman
* @Date: 2022-06-08-10:51
* @Description:
*/
@Service("file")
public class FileServiceImpl implements IFileService {
@Autowired
private IQiniuService qiniuService;
@Autowired
private ITikTokImage tikTokImage;
@Override
public ArrayList<TiktokImgVo> checkImg(ArrayList<MultipartFile> multipartFiles) {
ArrayList<TiktokImgVo> tiktokImgVos = new ArrayList<>();
//返回通过校验的数组
ArrayList<MultipartFile> multipartFileList = qiniuService.checkImageFormat(multipartFiles);
for (MultipartFile multipartFile : multipartFileList) {
TiktokImgVo tiktokImgVo = new TiktokImgVo();
String filename = multipartFile.getResource().getFilename();
tiktokImgVo.setFileName(filename);
String imageString = ImgUtil.getImageString(multipartFile);
String checkMsg = qiniuService.checkImageContent("data:application/octet-stream;base64," +imageString);
if (checkMsg.equals("pass")){
//抖音图片检测二次检测
if (tikTokImage.checkImageContent(multipartFile)) {
//可以通过
tiktokImgVo.setStatus("1");
tiktokImgVos.add(tiktokImgVo);
}else {
//不可以通过
tiktokImgVo.setStatus("2");
tiktokImgVos.add(tiktokImgVo);
}
continue;
}
if (checkMsg.equals("review")){
//人工审核
tiktokImgVo.setStatus("0");
tiktokImgVos.add(tiktokImgVo);
continue;
}
if (checkMsg.equals("block")){
//不可通过
tiktokImgVo.setStatus("2");
tiktokImgVos.add(tiktokImgVo);
continue;
}
}
return tiktokImgVos;
}
}

37
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/QiniuServiceImpl.java

@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.codec.Base64;
import com.bnyer.file.config.QiniuConfig;
import com.bnyer.file.service.IQiniuService;
import com.bnyer.file.utils.ImgUtil;
import com.bnyer.file.utils.StringUtil;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
@ -66,9 +67,9 @@ public class QiniuServiceImpl implements IQiniuService {
// 使用工具类根据上传文件生成唯一图片名称
String imgName = StringUtil.getRandomImgName(fileName);
if (!file.isEmpty()) {
FileInputStream inputStream =null;
InputStream inputStream =null;
try {
inputStream=(FileInputStream) file.getInputStream();
inputStream=(InputStream) file.getInputStream();
Response response = uploadManager.put(inputStream, imgName, token,null,null);
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
url=qiniuConfig.getUrl()+"/"+putRet.key;
@ -96,7 +97,8 @@ public class QiniuServiceImpl implements IQiniuService {
* @param imageUrl 图片的url地址或者图片Base64编码Base64编码请求时应在开头加上data:application/octet-stream;base64,
* @return JSONObject
*/
public JSONObject checkImageContent(String imageUrl) {
@Override
public String checkImageContent(String imageUrl) {
//基础参数拼接
String url = qiniuConfig.getQiniuCheckImgUrl();
String host = qiniuConfig.getQiniuHostUrl();
@ -130,7 +132,7 @@ public class QiniuServiceImpl implements IQiniuService {
if (checkMsg.equals("block")){
//不可通过
}
return checkResult;
return checkMsg;
} catch (QiniuException e) {
e.printStackTrace();
}
@ -143,7 +145,7 @@ public class QiniuServiceImpl implements IQiniuService {
* @param multipartFiles
* @return 格式正确的文件
*/
public static ArrayList<MultipartFile> checkImageFormat(ArrayList<MultipartFile> multipartFiles){
public ArrayList<MultipartFile> checkImageFormat(ArrayList<MultipartFile> multipartFiles){
ArrayList<MultipartFile> afterCheckFiles = new ArrayList<>();
for (MultipartFile multipartFile : multipartFiles) {
ArrayList<String> imageSuffixList = new ArrayList<>();
@ -207,31 +209,10 @@ public class QiniuServiceImpl implements IQiniuService {
}
return null;
}
public static String getImageString(String imageFile){
InputStream is = null;
try {
byte[] data = null;
is = new FileInputStream(new File(imageFile));
data = new byte[is.available()];
is.read(data);
return new String(Base64.encodeBase64(data));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != is) {
try {
is.close();
is = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
return "";
}
// public static void main(String[] args) {
//
// String imageString = getImageString("C:\\Users\\ASUS\\Documents\\WeChat Files\\wxid_vzk0z5ghy6q922\\FileStorage\\File\\2020-09\\20220608134731.png");
// String imageString = ImgUtil.getImageString("C:\\Users\\ASUS\\Documents\\WeChat Files\\wxid_vzk0z5ghy6q922\\FileStorage\\File\\2020-09\\20220608134731.png");
// JSONObject jsonObject = checkImageContent("data:application/octet-stream;base64," + imageString);
// System.out.println(JSON.parseObject(jsonObject.get("result").toString()).get("suggestion").toString());
// System.out.println(jsonObject);

47
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/TikTokImageServiceImpl.java

@ -1,11 +1,14 @@
package com.bnyer.file.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.codec.Base64;
import com.bnyer.file.config.TikTokConfig;
import com.bnyer.file.service.IQiniuService;
import com.bnyer.file.service.ITikTokImage;
import com.bnyer.file.utils.HttpUtils;
import com.bnyer.file.utils.ImgUtil;
import com.bnyer.file.utils.StringUtil;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
@ -18,6 +21,7 @@ import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@ -36,17 +40,12 @@ import java.util.HashMap;
*/
@Service("tiktokImage")
public class TikTokImageServiceImpl implements ITikTokImage {
@Value("${tiktok.appId}")
private static String appId;
@Autowired
private TikTokConfig tikTokConfig;
@Value("${tiktok.secret}")
private static String secret;
@Value("${tiktok.grant_type}")
private static String grant_type;
@Value("${qiniu.url}")
private String getTokenUrl="https://developer.toutiao.com/api/apps/v2/token";
private String checkImgUrl="https://developer.toutiao.com/api/apps/censor/image";
public static void main(String[] args) {
}
@ -54,15 +53,35 @@ public class TikTokImageServiceImpl implements ITikTokImage {
public Boolean checkImageContent(MultipartFile file) {
String token="";
HashMap<String, Object> param = new HashMap<>();
param.put("appId", appId);
param.put("secret", secret);
param.put("grant_type", grant_type);
param.put("appId", tikTokConfig.getAppId());
param.put("secret", tikTokConfig.getSecret());
param.put("grant_type", tikTokConfig.getGrant_type());
String body = JSON.toJSONString(param);
String res = HttpUtils.sendPost(getTokenUrl, body);
String err_tips = JSON.parseObject(res).get("err_tips").toString();
if (err_tips.equals("success")){
token=JSON.parseObject(err_tips).get("access_token").toString();
res=JSON.parseObject(res).get("data").toString();
token=JSON.parseObject(res).get("access_token").toString();
}
if (token!=""){
HashMap<String, Object> checkParam = new HashMap<>();
checkParam.put("app_id", tikTokConfig.getAppId());
checkParam.put("access_token", token);
checkParam.put("image_data", ImgUtil.getImageString(file));
String checkBody = JSON.toJSONString(checkParam);
String checkRes = HttpUtils.sendPost(checkImgUrl, checkBody);
JSONObject jsonObject = JSON.parseObject(checkRes);
JSONArray predicts = JSON.parseArray(jsonObject.get("predicts").toString());
for (Object predict : predicts) {
String hit = JSON.parseObject(predict.toString()).get("hit").toString();
if (hit.equals("true")) {
//System.out.println("不通过==========================");
return false;
}
//System.out.println(predict+"===================");
}
return true;
}
return null;
return false;
}
}

4
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/HttpUtils.java

@ -39,8 +39,8 @@ public class HttpUtils {
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数

134
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java

@ -1,17 +1,22 @@
package com.bnyer.file.utils;
import com.alibaba.nacos.common.codec.Base64;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
/**
* 图片处理工具类
@ -130,4 +135,133 @@ public class ImgUtil {
}
return flag;
}
/**
* 将图片转为base64字符串
* @param imageFile
* @return
*/
public static String getImageString(String imageFile){
InputStream is = null;
try {
byte[] data = null;
is = new FileInputStream(new File(imageFile));
data = new byte[is.available()];
is.read(data);
return new String(Base64.encodeBase64(data));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != is) {
try {
is.close();
is = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
return "";
}
/**
* 将图片转为base64字符串
* @param imageFile
* @return
*/
public static String getImageString(MultipartFile imageFile){
InputStream is = null;
try {
byte[] data = null;
byte [] byteArr=imageFile.getBytes();
is = new ByteArrayInputStream(byteArr);
data = new byte[is.available()];
is.read(data);
return new String(Base64.encodeBase64(data));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != is) {
try {
is.close();
is = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
return "";
}
/**
* 功能描述:将文件压缩到指定大小并上传
*
*
* @Param desFileSize: 指定文件大小单位为kb
* @Param accuracy:精度一般为0.5f
* @Param mutipartfile要压缩得图片
* @return: File
* @auther: qyh
* @date: 2022/7/3 19:17
*/
public static MultipartFile commpressPicCycle( long desFileSize, double accuracy,MultipartFile mutipartfile) throws IOException{
String originalFilename = mutipartfile.getOriginalFilename();
String[] filename = originalFilename.split("\\.");
File fileConver = convertFile(mutipartfile);
long fileSize = FileUtils.sizeOf(fileConver);
InputStream fileInputStream = new FileInputStream(fileConver);
// 判断图片大小是否小于指定图片大小
if(fileSize <= desFileSize * 1024){
return new MockMultipartFile("mutilConver."+filename[1],mutipartfile.getOriginalFilename(),"text/plain",fileInputStream);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
byte[] b=new byte[1024];
int n;
while ((n=fileInputStream.read(b))!=-1){
bos.write(b,0,n);
}
byte[] bytes = bos.toByteArray();
//计算宽高
BufferedImage bim = ImageIO.read(new ByteArrayInputStream(bytes));
int imgWidth = bim.getWidth();
int imgHeight = bim.getHeight();
int desWidth = new BigDecimal(imgWidth).multiply( new BigDecimal(accuracy)).intValue();
int desHeight = new BigDecimal(imgHeight).multiply( new BigDecimal(accuracy)).intValue();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //字节输出流(写入到内存)
//Thumbnails.of(new ByteArrayInputStream(bytes)).size(desWidth, desHeight).outputQuality(accuracy).toOutputStream(baos);
Thumbnails.of(fileConver).size(desWidth, desHeight).outputQuality(accuracy).toFile(fileConver);
System.out.println(fileConver.length()+"==========================");
InputStream inputStream = new FileInputStream(fileConver);
mutipartfile=new MockMultipartFile("mutilConver."+filename[1],mutipartfile.getOriginalFilename(),"text/plain",inputStream);
System.out.println(mutipartfile.getSize()+"=====================");
fileInputStream.close();
bos.close();
//如果不满足要求,递归直至满足要求
return commpressPicCycle(desFileSize,accuracy, mutipartfile);
}
/**
* 將MutipartFile轉file
* @param multipartFile
* @return
*/
public static File convertFile(MultipartFile multipartFile) {
File file = null;
try {
String originalFilename = multipartFile.getOriginalFilename();
String[] filename = originalFilename.split("\\.");
if (filename[0].length()<3){
filename[0]=filename[0]+"plus";
}
file = File.createTempFile(filename[0], "."+filename[1]);
multipartFile.transferTo(file);
file.deleteOnExit();
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
}

45
bnyer-services/bnyer-file/src/main/java/com/bnyer/file/vo/TiktokImgVo.java

@ -0,0 +1,45 @@
package com.bnyer.file.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
@ApiModel("抖音图片响应类")
public class TiktokImgVo implements Serializable {
@ApiModelProperty(value="id")
private Long id;
@ApiModelProperty(value="图片地址")
private String imgUrl;
@ApiModelProperty(value="用户id")
private Long creatorId;
@ApiModelProperty(value="分类id")
private Long typeId;
@ApiModelProperty(value="下载量")
private Integer downloadNum;
@ApiModelProperty(value="点赞量")
private Integer greatNum;
@ApiModelProperty(value="收藏量")
private Integer collectionNum;
@ApiModelProperty(value="状态(0->待审核;1->审核通过;2->审核拒绝)")
private String status;
@ApiModelProperty(value="是否热门(0->冷门;1->热门)")
private String isHot;
private String fileName;
private static final long serialVersionUID = 1L;
}

2
bnyer-services/bnyer-file/src/main/resources/bootstrap.yml

@ -12,7 +12,7 @@ spring:
name: bnyer-file
profiles:
# 环境配置
active: dev
active: prod
servlet:
multipart:
maxFileSize: 5MB

Loading…
Cancel
Save