文章目录
1.Java实现微信小程序校验图片是否含有违法违规内容(security.imgSecCheck)
做毕设期间,第一次对微信小程序的开发接口进行对接,发现微信的接口文档写的及其简单,导致我找寻许久都没有找到合适的介绍,在此记录自己使用Java在后台对接security.imgSecCheck接口的过程。微信校验一张图片是否含有违法违规内容。
2.接口文档简述
应用场景举例:
1.图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等;
2.敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。
频率限制:
单个 appId 调用上限为 2000 次/分钟,200,000 次/天*(图片大小限制:1M) *服务市场:**通过服务市场使用可以有更多的能力,文档详情。
调用方式:
HTTPS 调用
云调用
增量调用(加强版)
本人使用的是https调用,请求地址如下:
POST https://api.weixin.qq.com/wxa/img_sec_check?access_token=ACCESS_TOKEN
请求参数如下:
可以看到想要对接微信开发接口,必须要有其提供的AccessToken,如何获取AccessToken在我上篇博客中以介绍,不再累赘。
该接口对校验的图片有要求,一是大小不能超过1M,二是图片尺寸不超过750px * 1334px。
3.Java实现对接接口
使用了httpclient,可通过这篇文章(HttpClient详细使用示例)了解其使用方法。
首先,导入maven依赖包。
<!--调用 http 请求-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
在代码编写过程,自动导包有时候会有一些相同的包,但是却不知道用哪一个,有可能导入了其他的包,我在网上查找资料时经常遇到代码没有列出需要导的包的情况,在此添加部分需要的包,大概可知所需要的包。(因为代码是从模块中分离出来的,可能有所纰漏)。Java代码如下:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* 恶意图片过滤
* MultipartFile multipartFile, String accessToken
* @param multipartFile
* @param accessToken
* @return
*/
public void checkImg(MultipartFile multipartFile, String accessToken) throws Exception {
//微信开放接口链接
String url = "https://api.weixin.qq.com/wxa/img_sec_check?access_token=" + accessToken;
// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的
HttpClient httpclient = HttpClients.createDefault();
//创建一个post请求
HttpPost request = new HttpPost(url);
//设置响应头 ( application/octet-stream:二进制流,不知道下载文件类型)
request.addHeader("Content-Type", "application/octet-stream");
//输入流,获取输入图片的输入流
InputStream inputStream = multipartFile.getInputStream();
try {
//创建一个byte数组,和输入的文件输入流大小一样
byte[] byt = new byte[inputStream.available()];
//从输入流中读取全部,并将其存储在缓冲区数组byt 中。
inputStream.read(byt);
//定制提交内容
request.setEntity(new ByteArrayEntity(byt, ContentType.create("image/jpg")));
由客户端执行(发送)请求,执行校验
HttpResponse response = httpclient.execute(request);
// 从响应模型中获取响应实体
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");// 转成string
//打印校验结果
System.out.println("result:" + result);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
至此可以实现校验结果,检验成功与否对比上图。检验图片吗,嗯…,自行获取≖‿≖✧ o‿≖✧(๑•̀ㅂ•́)و✧
4.压缩图片(Thumbnails)
微信这个接口对图片的大小和尺寸有着严格要求,但是不能要求用户自行对图片进行操作符合我程序的要求,所以需要在对图片进行检验之前对其压缩以及达到图片尺寸。使用Thumbnails。
Thumbnails是谷歌的一个图片压缩处理开源库(虽然现在好像已经不再更新了),利用这个库可以容易的对图片进行一些处理,例如压缩图片、变换图片格式之类的。可参考这篇文章java处理图片类库 Thumbnails 学习
1.首先导入maven依赖
<!--压缩图片-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
2.压缩图片java代码
这里压缩图片是为了对上面的检测代码而编写的,所以选择返回一个输入流,这样可直接对接这两个功能。
在使用Thumbnails过程中发现,Thumbnails对不是jpg格式的图片进行压缩之后,获取其输入流会出现错误,所以在进行压缩之前,要先对图片进行转换,将其他格式的图片变成jpg格式。
经测试,7M左右的图片压缩之后100kb左右,不支持指定大小的压缩,支持指定尺寸大小。
import org.apache.commons.io.FileUtils;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import net.coobird.thumbnailator.Thumbnails;
/**
* 压缩图片
* @param multipartFile
*/
public inputStream compressImage(MultipartFile multipartFile){
//*************对不是jpg格式的图片转换成jpg格式***************
//获取文件名后缀,判断其格式
int begin = multipartFile.getOriginalFilename().lastIndexOf(".");
int last = multipartFile.getOriginalFilename().length();
//获得文件后缀名
String houzuiFileName = multipartFile.getOriginalFilename().substring(begin, last);
//创建临时文件
File tempFile = new File(multipartFile.getOriginalFilename());
//写入临时File文件 tempFile,将multipartFile转换成File
try {
//import org.apache.commons.io.FileUtils;
FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), tempFile);
} catch (IOException e) {
e.printStackTrace();
}
//如果文件不是jpg格式,转换其格式
if (!"jpg".equalsIgnoreCase(houzuiFileName)){
//ImageUtils是一个工具类,下面给出
//将png格式转换成jpg,输出到tempFile
ImageUtils.convert(multipartFile.getOriginalFilename(), "jpg", tempFile.getAbsolutePath());//测试OK
//*************对不是jpg格式的图片转换成jpg格式***************
}
try {
//压缩图片
BufferedImage bufferedImage = Thumbnails.of(tempFile)
.size(740, 1330)//指定压缩之后的图片尺寸
.outputQuality(0.8f)//图片压缩质量
.asBufferedImage();
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", os);
InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
// System.out.println(inputStream);
return inputStream;
} catch (IOException e) {
e.printStackTrace();
}finally {
// 会在本地产生临时文件,用完后需要删除
if (tempFile.exists()) {
tempFile.delete();
}
}
return null;
}
5.整合压缩图片和对接代码
/**
* 恶意图片过滤
* MultipartFile multipartFile, String accessToken
* @param multipartFile
* @param accessToken
* @return
*/
@ApiOperation(value="校验图片是否含有违法违规内容", notes="校验一张图片是否含有违法违规内容")
@PostMapping("checkImg")
public void checkImg(MultipartFile multipartFile, String accessToken) throws Exception {
//压缩图片
InputStream inputStream = compressImage(multipartFile);
String url = "https://api.weixin.qq.com/wxa/img_sec_check?access_token=" + accessToken;
// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的
HttpClient httpclient = HttpClients.createDefault();
//创建一个post请求
HttpPost request = new HttpPost(url);
//设置响应头 ( application/octet-stream:二进制流,不知道下载文件类型)
request.addHeader("Content-Type", "application/octet-stream");
try {
//创建一个byte数组,和输入的文件的大小一样
byte[] byt = new byte[inputStream.available()];
//从输入流中读取全部,并将其存储在缓冲区数组byt 中。
inputStream.read(byt);
//定制提交内容
request.setEntity(new ByteArrayEntity(byt, ContentType.create("image/jpg")));
由客户端执行(发送)请求,执行校验
HttpResponse response = httpclient.execute(request);
// 从响应模型中获取响应实体
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");// 转成string
//打印校验结果
System.out.println("result:" + result);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6.ImageUtils工具类
ImageUtils工具类:
//import Java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import static jdk.nashorn.internal.runtime.regexp.joni.Syntax.Java;
/**
* 图片处理工具类:<br>
* 功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
* @author Administrator
*/
public class ImageUtils {
/**
* 几种常见的图片格式
*/
public static String IMAGE_TYPE_GIF = "gif";// 图形交换格式
public static String IMAGE_TYPE_JPG = "jpg";// 联合照片专家组
public static String IMAGE_TYPE_JPEG = "jpeg";// 联合照片专家组
public static String IMAGE_TYPE_BMP = "bmp";// 英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式
public static String IMAGE_TYPE_PNG = "png";// 可移植网络图形
public static String IMAGE_TYPE_PSD = "psd";// Photoshop的专用格式Photoshop
/**
* 程序入口:用于测试
* @param args
*/
public static void main(String[] args) {
// -图像类型转换:
ImageUtils.convert("D:/IMG_20180811_222034.png", "jpg", "D:/test.jpg");//测试OK
}
/**
* 图像类型转换:GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG
* @param srcImageFile 源图像地址
* @param formatName 包含格式非正式名称的 String:如JPG、JPEG、GIF等
* @param destImageFile 目标图像地址
*/
public final static void convert(String srcImageFile, String formatName, String destImageFile) {
try {
File f = new File(srcImageFile);
f.canRead();
f.canWrite();
BufferedImage src = ImageIO.read(f);
ImageIO.write(src, formatName, new File(destImageFile));
} catch (Exception e) {
e.printStackTrace();
}
}
}
7.结束语
以上代码都已经经过测试,可实现功能。如果出现的纰漏或者bug还希望各位多多提醒。欢迎━(`∀´)ノ亻!交流。