Skip to content

Commit 75bd5d3

Browse files
committed
���浣�榛�璁ょ嚎绋���帮����板�������ゆ�����浠跺��绾跨����伴��璁剧疆���椤�
1 parent 4c3469d commit 75bd5d3

8 files changed

Lines changed: 71 additions & 39 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
*.class
2+
QGroupFace/bin/
23

34
# Mobile Tools for Java (J2ME)
45
.mtj.tmp/

QGroupFace/src/service/Config.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package service;
2+
3+
public class Config {
4+
public static String srcPath = "";
5+
public static String destPath = ""; // 绝对路径
6+
public static boolean delSrcFile = false; //是否删除源图片
7+
public static int threadNum = 5; //太多会在网络上处理不过来
8+
9+
public static String API_KEY = "4480afa9b8b364e30ba03819f3e9eff5";
10+
public static String API_SECRET = "Pz9VFT8AP3g_Pz8_dz84cRY_bz8_Pz8M";
11+
12+
public static void initConfig(String srcPath,String destPath,boolean delSrcFile,int threadNum) {
13+
Config.srcPath = srcPath;
14+
Config.destPath = destPath;
15+
Config.delSrcFile = delSrcFile;
16+
Config.threadNum = threadNum;
17+
}
18+
}

QGroupFace/src/service/FileThread.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class FileThread implements Runnable {
1818
private AtomicInteger femaleIndex = new AtomicInteger(1);
1919

2020
private HttpRequests httpRequests = new HttpRequests(
21-
Main.API_KEY, Main.API_SECRET, true, true);
21+
Config.API_KEY, Config.API_SECRET, true, true);
2222

2323
private static String getGenderOrNull(JSONObject result) {
2424
String gender;
@@ -42,14 +42,15 @@ public void run() {
4242
if (cnt <= list.size() - 1) {
4343
file = list.get(cnt);cnt++;
4444
}
45-
} //unlock
45+
} //解锁
4646

4747
JSONObject result = null;
4848
try {
4949
result = httpRequests.detectionDetect(new PostParameters()
5050
.setImg(file).setAttribute("gender"));
5151
} catch (FaceppParseException e) {
52-
e.printStackTrace();
52+
System.out.println("Error:\t" + file.getName() + " => " + e.getErrorMessage());
53+
continue;
5354
}
5455

5556
String gender = getGenderOrNull(result);
@@ -62,17 +63,21 @@ public void run() {
6263
index = maleIndex.getAndIncrement();
6364
}
6465

65-
//some file are ends with null : ZJ0P65PZN$CW6IU)2PJVMDQ.null
66+
//有些图片是.null后缀如 : ZJ0P65PZN$CW6IU)2PJVMDQ.null
6667
String destSuffix = FileUtils.getFileSuffix(file);
6768
if(destSuffix.equals("null")){
6869
destSuffix = "jpg";
6970
}
70-
FileUtils.fileChannelCopy(file, new File(Main.destPath
71+
FileUtils.fileChannelCopy(file, new File(Config.destPath
7172
+ "\\" + gender + "\\" + index + "." + destSuffix));
72-
73+
7374
System.out.println(Thread.currentThread().getName() + "\t"
7475
+ file.getName() + " -> "
7576
+ gender + "\\" + index + "." + destSuffix );
77+
78+
if(Config.delSrcFile){ //删源文件
79+
file.delete();
80+
}
7681
}
7782

7883
}

QGroupFace/src/service/FileUtils.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
import java.nio.channels.FileChannel;
88

99
public class FileUtils {
10-
private static final long FILE_SIZE_MIN = 10240;// 10kb
10+
private static final long FILE_SIZE_MIN = 12288;// 12kb
1111
private static final long FILE_SIZE_MAX = 1048576; // 1M
1212

1313
/**
14-
* fliter files that are obviously illegal
14+
* 初步过滤不含皂片的文件
1515
* @param file
1616
* @return
1717
*/
@@ -27,7 +27,7 @@ public static boolean canFliter(File file ) {
2727
}
2828

2929
/**
30-
* create directory that needed
30+
* 如果目标目录不存在就新建,包括其性别分类子目录
3131
* @param destPath
3232
*/
3333
public static void initDestFileDir(String destPath) {
@@ -50,7 +50,7 @@ public static String getFileSuffix(File file) {
5050
}
5151

5252
/**
53-
* copy file
53+
* 复制文件
5454
* @param src
5555
* @param dest
5656
*/

QGroupFace/src/service/Main.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,27 @@
66

77
public class Main {
88

9-
public static String srcPath = "";
10-
public static String destPath = ""; // absolute path better, no any other file better
11-
12-
public static String API_KEY = "4480afa9b8b364e30ba03819f3e9eff5";
13-
public static String API_SECRET = "Pz9VFT8AP3g_Pz8_dz84cRY_bz8_Pz8M";
14-
15-
private static final int threadNumber = 20;
16-
179
public static void main(String[] args) {
18-
if(args.length==2){
19-
srcPath = args[0];destPath = args[1];
10+
if(args.length == 2){
11+
Config.initConfig(args[0],args[1],false,Config.threadNum);
12+
}else if(args.length == 3){
13+
Config.initConfig(args[0],args[1],args[2].toUpperCase().equals("Y"),Config.threadNum);
14+
}else if(args.length == 4){
15+
Config.initConfig(args[0],args[1],args[2].toUpperCase().equals("Y"),Integer.parseInt(args[3]));
2016
}
21-
FileUtils.initDestFileDir(destPath);
17+
FileUtils.initDestFileDir(Config.destPath);
2218

2319
try {
24-
List<File> list = getFliteredFileList(srcPath);
25-
System.out.println("After fliter "+list.size()+" files leave");
20+
List<File> list = getFliteredFileList(Config.srcPath);
21+
System.out.println("After fliter files number: "+list.size());
22+
System.out.println("Thread number: " + Config.threadNum );
23+
System.out.println("Delete sources picture: " + Config.delSrcFile);
24+
System.out.println();
2625

2726
FileThread fileThread = new FileThread();
2827
fileThread.setList(list);
2928

30-
Thread[] threads = new Thread[threadNumber];
29+
Thread[] threads = new Thread[Config.threadNum];
3130
for (int i = 0; i < threads.length; i++) {
3231
threads[i] = new Thread(fileThread,"Thread-"+ (int)(i+1));
3332
threads[i].start();

README.md

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,42 @@
11
# Q群爆照图片查找
22

3-
通过 Face++ API 实现在QQ群图片记录里查找爆照图片,**包括被撤销的图片**学生招新新生群必备良品
3+
通过 Face++ API 实现在QQ群图片记录里查找爆照图片,**包括被撤销的图片**学校新生咨询群必备良品
44

5-
实际效果不会有漏网鱼,对女性的脸识别还好,但男脸就会有不少表情包混进来,谁让表情包也是人脸。![](image/sad.jpg)
5+
实际效果不会有漏网之鱼,对女性的脸识别还好,但男脸就会有不少表情包混进来,谁让表情包也是人脸。![](image/sad.jpg)
66

77
## 实现
8-
Windows版QQ在收到Q群图片后会将图片存在 `数据目录\Q号\Image\Group\` ,即使对方撤销也不会被删除。所以遍历该目录下的图片,初步过滤后将剩余文件交给人脸识别API,把带人脸的图片复制到新目录。
8+
Windows版QQ在收到Q群图片后会将图片存在 `数据目录\Q号\Image\Group\` (该目录默认在*我的文档* 里),即使对方撤销也不会被删除。所以遍历该目录下的图片,初步过滤后将剩余文件交给人脸识别API,把带人脸的图片复制到新目录。
99

1010
### 过滤
11-
1. 文件大小 < 10KB 或 > 1MB
11+
1. 文件大小 < 12KB 或 > 1MB
1212
2. gif 后缀
1313
3. 大量白色边框的表情包(未实现)
1414

1515
## 用法
1616
不改动代码的情况下
1717

18-
java -jar QGroupFace.jar 源图片目录 输出目录
19-
java -jar QGroupFace.jar 源图片目录 输出目录 >> log.txt
18+
java -jar QGroupFace.jar 源图片目录 输出目录 [复制后是否删源文件(Y/N)] [线程数(默认5)]
2019

21-
如 java -jar QGroupFace.jar E:\Software\QQ_data\10000\Image\Group\Image1 E:\Image1
20+
如:查找并复制
2221

23-
然后慢慢等待,3-20分钟不等。
22+
java -jar QGroupFace.jar E:\Software\QQ_data\10000\Image\Group\Image1 E:\Image1
23+
24+
复制后删除源文件且设置线程数为6(建议小于10)
25+
26+
java -jar QGroupFace.jar 源图片目录 输出目录 Y 6
27+
28+
如需将输出重定向到当前目录文本里则加上 `>> log.txt` 即可。
29+
30+
31+
然后慢慢等待,10-20分钟不等,五个线程情况下1200个文件大概需要10分钟。
2432

2533
## 注意事项
26-
1. 使用前建议***先用QQ自带的消息删除器删除很久前的图片***,且用[批处理文件](release/doFliter.bat)过滤删除一些不太可能是皂片的文件。
27-
2. 调用API需要 `API Key``API Secret`,代码里已使用官方的测试Key,好像是体验版,并发限制为1,也可以注册后自己替换,注册版是并发限制3。
28-
3. QQ有些图片是 `.null` 为后缀,实际上是图片,默认当作 `jpg` 处理。
29-
4. QQ有些动图也被保存为 jpg 格式。
30-
5. 由于face++的返回的json项太多固不格式化为对象了,直接正则判断是否成功。
34+
1. 使用前建议***先用QQ自带的消息删除器删除很久前的图片***,可以的话也用[批处理文件(记得改路径)](release/doFliter.bat)过滤删除一些不太可能是皂片的文件。
35+
2. 调用API需要 `API Key``API Secret`,代码里已使用官方的测试Key,貌似是上线版(不限制并发数),而自己注册的账号默认是并发数限制为3。
36+
3. 线程数设置太高可能导致face++反馈异常。
37+
4. QQ有些图片是 `.null` 为后缀,实际上是图片,默认当作 `jpg` 处理。
38+
5. QQ有些动图也被保存为 jpg 格式。
39+
6. 由于face++的返回的json项太多就不格式化为对象了,直接正则判断是否成功。
3140

3241
## License
3342
**The MIT License**

release/QGroupFace.jar

819 Bytes
Binary file not shown.

release/doFliter.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
set delPath=E:\Software\QQ_data\10000\Image\Group\Image1
44
echo clean : %delPath%
55

6-
::<10kb
7-
for /r %delPath% %%i in (*) do @(if %%~zi lss 10240 del "%%i" /f)
6+
::<12kb
7+
for /r %delPath% %%i in (*) do @(if %%~zi lss 12288 del "%%i" /f)
88
::>1Mb
99
for /r %delPath% %%i in (*) do @(if %%~zi gtr 1048576 del "%%i" /f)
1010
::gif

0 commit comments

Comments
 (0)