diff --git a/.classpath b/.classpath index c1667f6..a5375a7 100644 --- a/.classpath +++ b/.classpath @@ -12,5 +12,6 @@ + diff --git a/README.md b/README.md index 2c23c4a..3760658 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # antiplag 程序代码及文档作业相似度检查软件 -软件主要检查、比较学生提交的电子档作业之间的相似度,能对多种编程语言(如java、c/c++、python等)、多种格式(txt、doc、docx、pdf等)的中英文、简繁体文档(如实验报告)之间的文本相似度进行比较分析,输出相似度高的文档,进而辅助发现学生之间互相抄袭的行为。 +软件主要检查、比较学生提交的电子档作业之间的相似度,能对多种编程语言(如java、c/c++、python等)、多种格式(txt、doc、docx、pdf等)的中英文、简繁体文档之间的文本、多种格式(png、jpg、gif、bmp等)的图片相似度进行比较分析,输出相似度高的文档、图片,进而辅助发现学生之间互相抄袭的行为。 ## 需求 [jdk11](https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html) @@ -14,7 +14,7 @@ ![程序主界面](./maingui.png) ## 原理 -系统采用的主要技术是字符串相似度比较算法、代码词法语法解析、自然语言处理(nlp)中的分词。 +系统采用的主要技术是字符串相似度比较算法、代码词法语法解析、自然语言处理(nlp)中的分词、图片相似度比较算法。 程序类文本的相似度比较基于3个开放系统: * 一是基于网络服务的[MOSS系统](http://theory.stanford.edu/~aiken/moss/)(斯坦福大学开放的支持多种编程语言代码相似度比较的系统); @@ -33,6 +33,10 @@ 第二种是基于jplag的GST算法,对其功能进行了扩展,增加的“doc”语言类型,可以对各种文档进行相似度计算,并提供基于网页的可视化比对功能。 +图片的相似度比较基于[JImageHash项目](https://github.com/KilianB/JImageHash): + +主要采用了图片phash指纹相似度比较算法。 + ### 参考文献: 1. [Software Plagiarism Detection Techniques:A Comparative Study](http://www.ijcsit.com/docs/Volume%205/vol5issue04/ijcsit2014050441.pdf) 2. [JPlag: Finding plagiarisms among a set of programs](http://page.mi.fu-berlin.de/prechelt/Biblio/jplagTR.pdf) @@ -42,7 +46,7 @@ ## TODO 1. 将jplag整合进系统。已实现。 2. 支持html,jsp文件代码的查重。 -3. 支持图片文件查重。 +3. 支持图片文件查重。已实现。 4. 开发web版作业查重软件。 5. 支持存储以往作业文档,支持基于数据库的作业查重。 @@ -51,5 +55,6 @@ ## 更新情况 1. 2019.12.1 使用hanlp作为分词组件,支持pdf、html文件文本的查重,修复若干bug,发布v2.8.6版。 2. 2019.12.3 扩展jplag功能,提供“doc”语言类型,实现了对多种格式文档文本的相似度计算及可视化比对功能。更新使用帮助,测试数据,发布v2.8.8版。 +3. 2019.12.25 实现图片相似比较功能,使用phash,实现了对多种格式图片的相似比较。更新测试数据,文档,发布版v3.0.0版。 \ No newline at end of file diff --git a/bin/.gitignore b/bin/.gitignore index 67c6176..de715a7 100644 --- a/bin/.gitignore +++ b/bin/.gitignore @@ -1,5 +1,5 @@ /preprocess/ -/gui/ -/jplag/ -/utils/ /shingle/ +/utils/ +/gui/ +/imghash/ diff --git a/bin/gui/plag/edu/PlagGUI$1.class b/bin/gui/plag/edu/PlagGUI$1.class index a4f5b55..d6a2513 100644 Binary files a/bin/gui/plag/edu/PlagGUI$1.class and b/bin/gui/plag/edu/PlagGUI$1.class differ diff --git a/bin/gui/plag/edu/PlagGUI$2.class b/bin/gui/plag/edu/PlagGUI$2.class index 643b0b2..517057a 100644 Binary files a/bin/gui/plag/edu/PlagGUI$2.class and b/bin/gui/plag/edu/PlagGUI$2.class differ diff --git a/bin/gui/plag/edu/PlagGUI$3.class b/bin/gui/plag/edu/PlagGUI$3.class index 080dcbb..ee8ca9f 100644 Binary files a/bin/gui/plag/edu/PlagGUI$3.class and b/bin/gui/plag/edu/PlagGUI$3.class differ diff --git a/bin/gui/plag/edu/PlagGUI$4.class b/bin/gui/plag/edu/PlagGUI$4.class index e9667d2..97c9218 100644 Binary files a/bin/gui/plag/edu/PlagGUI$4.class and b/bin/gui/plag/edu/PlagGUI$4.class differ diff --git a/bin/gui/plag/edu/PlagGUI$5.class b/bin/gui/plag/edu/PlagGUI$5.class index 41d3178..4f20f61 100644 Binary files a/bin/gui/plag/edu/PlagGUI$5.class and b/bin/gui/plag/edu/PlagGUI$5.class differ diff --git a/bin/gui/plag/edu/PlagGUI$6.class b/bin/gui/plag/edu/PlagGUI$6.class index 1ebf030..9279da5 100644 Binary files a/bin/gui/plag/edu/PlagGUI$6.class and b/bin/gui/plag/edu/PlagGUI$6.class differ diff --git a/bin/gui/plag/edu/PlagGUI$7.class b/bin/gui/plag/edu/PlagGUI$7.class index 4690a5d..33b1828 100644 Binary files a/bin/gui/plag/edu/PlagGUI$7.class and b/bin/gui/plag/edu/PlagGUI$7.class differ diff --git a/bin/gui/plag/edu/PlagGUI$8.class b/bin/gui/plag/edu/PlagGUI$8.class index 97f46d1..291d3b4 100644 Binary files a/bin/gui/plag/edu/PlagGUI$8.class and b/bin/gui/plag/edu/PlagGUI$8.class differ diff --git a/bin/gui/plag/edu/PlagGUI$9.class b/bin/gui/plag/edu/PlagGUI$9.class index dbb0182..98d2f10 100644 Binary files a/bin/gui/plag/edu/PlagGUI$9.class and b/bin/gui/plag/edu/PlagGUI$9.class differ diff --git a/bin/gui/plag/edu/PlagGUI.class b/bin/gui/plag/edu/PlagGUI.class index 52073d0..eda3a9e 100644 Binary files a/bin/gui/plag/edu/PlagGUI.class and b/bin/gui/plag/edu/PlagGUI.class differ diff --git a/bin/jplag/doc/DocToken.class b/bin/jplag/doc/DocToken.class new file mode 100644 index 0000000..e789b3b Binary files /dev/null and b/bin/jplag/doc/DocToken.class differ diff --git a/bin/jplag/doc/Language.class b/bin/jplag/doc/Language.class new file mode 100644 index 0000000..6dcbc83 Binary files /dev/null and b/bin/jplag/doc/Language.class differ diff --git a/bin/jplag/doc/Parser.class b/bin/jplag/doc/Parser.class new file mode 100644 index 0000000..793c5a6 Binary files /dev/null and b/bin/jplag/doc/Parser.class differ diff --git a/bin/jplag/doc/TokenStructure.class b/bin/jplag/doc/TokenStructure.class new file mode 100644 index 0000000..df387c7 Binary files /dev/null and b/bin/jplag/doc/TokenStructure.class differ diff --git a/bin/jplag/options/CommandLineOptionsExt.class b/bin/jplag/options/CommandLineOptionsExt.class new file mode 100644 index 0000000..d8b627c Binary files /dev/null and b/bin/jplag/options/CommandLineOptionsExt.class differ diff --git a/bin/shingle/plag/edu/ShingleSim.class b/bin/shingle/plag/edu/ShingleSim.class index 504264b..fbfae73 100644 Binary files a/bin/shingle/plag/edu/ShingleSim.class and b/bin/shingle/plag/edu/ShingleSim.class differ diff --git a/help.txt b/help.txt index 2f8843f..1621337 100644 --- a/help.txt +++ b/help.txt @@ -27,6 +27,12 @@ docx ʽĵƶȣֻ֧ҳĿӻȶԡ롰롱IJͬ⹤ѡ JplagѡdocɡJplagµtext͸ʺϼⴿӢĵƶȡ +3 ͼƬƶȼ +1ѡ񱻼ͼƬļĿ¼testdataµimgsĿ¼ +2ȷȷҵǡͼƬ +3ִбȽϡ +4鿴 + ׼ ϵͳ֧2ʽ. diff --git a/lib/jimagehash3.0.jar b/lib/jimagehash3.0.jar new file mode 100644 index 0000000..116ee4e Binary files /dev/null and b/lib/jimagehash3.0.jar differ diff --git a/maingui.png b/maingui.png index eefca2c..b1e19d2 100644 Binary files a/maingui.png and b/maingui.png differ diff --git a/out.txt b/out.txt index a703264..3c59004 100644 --- a/out.txt +++ b/out.txt @@ -1,63 +1 @@ -1 99.51535% dongxiao-2.doc dongxiaogbk.txt -2 92.47312% gumingzhu-2.doc zhucuiyun_2.doc -3 91.408936% wangmeng-2.doc zhucuiyun_2.doc -4 87.63636% dongxiao-2.docx dongxiaoutf8-2.txt -5 84.765625% dongxiao-2.docx dongxiao-2.html -6 84.717606% gumingzhu-2.doc wangmeng-2.doc -7 84.310844% dongxiao-2.doc dongxiao-2.pdf -8 84.168015% dongxiao-2.doc dongxiaoutf8-2.txt -9 83.870964% dongxiao-2.pdf dongxiaogbk.txt -10 83.68336% dongxiaogbk.txt dongxiaoutf8-2.txt -11 83.14176% dongxiao-2.html dongxiaoutf8-2.txt -12 82.954544% dongxiao-2.docx dongxiaogbk.txt -13 82.552505% dongxiao-2.doc dongxiao-2.docx -14 75.74404% lijie-2.doc wangmeng-2.doc -15 74.96063% gumingzhu-2.doc wuchangqing-2.doc -16 71.703705% dongxiao-2.pdf dongxiaoutf8-2.txt -17 71.49254% dongxiao-2.docx dongxiao-2.pdf -18 70.34036% dongxiao-2.html dongxiaogbk.txt -19 70.0% dongxiao-2.doc dongxiao-2.html -20 69.92366% wuchangqing-2.doc zhucuiyun_2.doc -21 68.584076% lijie-2.doc zhucuiyun_2.doc -22 65.61151% wangmeng-2.doc wuchangqing-2.doc -23 65.12301% gumingzhu-2.doc lijie-2.doc -24 60.869564% dongxiao-2.html dongxiao-2.pdf -25 57.454544% dongxiaogbk.txt meitao-2.doc -26 57.246376% dongxiao-2.doc meitao-2.doc -27 52.258064% lijie-2.doc wuchangqing-2.doc -28 50.757576% dongxiao-2.docx meitao-2.doc -29 50.284416% dongxiao-2.pdf meitao-2.doc -30 48.87218% makai2.doc wangxuan_2.doc.doc -31 48.45869% dongxiaoutf8-2.txt meitao-2.doc -32 46.67074% liuchuanyang-2.doc tangwenpeng-2.doc -33 41.878174% dongxiao-2.html meitao-2.doc -34 41.64096% heliwen_2.doc liufan_2.doc -35 40.54834% liufan_2.doc wangchunming_2.doc -36 38.75061% gechunlong-2.doc hanchao_2.doc -37 36.930233% luxiang-2.doc tangwenpeng-2.doc -38 36.89095% jiangfeng-2.doc lijie-2.doc -39 35.925926% weixiao-2.doc yinxu-2.doc -40 35.424637% liuchuanyang-2.doc wuliangchao-2.doc -41 35.039577% gechunlong-2.doc yinxu-2.doc -42 34.839073% gechunlong-2.doc weixiao-2.doc -43 34.325184% wangmeng-2.doc wuliangchao-2.doc -44 34.069096% guozhiquan -2.doc wuliangchao-2.doc -45 33.98907% wuliangchao-2.doc zhucuiyun_2.doc -46 32.858547% tangwenpeng-2.doc xuqiwei-2.doc -47 32.557137% tangwenpeng-2.doc wangchen-2.doc -48 32.296955% liuchuanyang-2.doc yinxu-2.doc -49 32.073547% lijie-2.doc wuliangchao-2.doc -50 32.070206% gechunlong-2.doc wangchen-2.doc -51 32.058823% jiangfeng-2.doc yinpeiyan_2.doc -52 31.946404% sunxiaolei-2.doc wangchunming_2.doc -53 31.471535% gumingzhu-2.doc wuliangchao-2.doc -54 30.698889% sunxiaolei-2.doc yinxu-2.doc -55 30.651136% liuchuanyang-2.doc xuqiwei-2.doc -56 30.63007% heliwen_2.doc wangchunming_2.doc -57 30.559345% liuchuanyang-2.doc weixiao-2.doc -58 30.494392% wangchen-2.doc xuqiwei-2.doc -59 30.429863% tangwenming-2.doc xuqiwei-2.doc -60 30.424183% tangwenming-2.doc wangchen-2.doc -61 30.095451% sunxiaolei-2.doc tangwenpeng-2.doc -62 30.065361% guozhiquan -2.doc liuchuanyang-2.doc -from fh Mon Dec 02 19:18:34 CST 2019 \ No newline at end of file +from fh Wed Dec 25 20:57:21 CST 2019 \ No newline at end of file diff --git a/src/gui/plag/edu/PlagGUI.java b/src/gui/plag/edu/PlagGUI.java index 697d8cf..d985476 100644 --- a/src/gui/plag/edu/PlagGUI.java +++ b/src/gui/plag/edu/PlagGUI.java @@ -34,6 +34,7 @@ import org.jvnet.substance.SubstanceLookAndFeel; import org.jvnet.substance.skin.BusinessBlueSteelSkin; +import imghash.plag.edu.ImageSim; import moss.plag.edu.Http; import shingle.plag.edu.ShingleSim; @@ -53,6 +54,7 @@ public class PlagGUI extends JFrame { WinCMD cmd; + private JRadioButton radBntImage; /** * Launch the application. */ @@ -125,6 +127,7 @@ public void stateChanged(ChangeEvent arg0) { && combLang!=null){ combMethod.setEnabled(true); // ʹ㷨ѡť combLang.setEnabled(true); + txtThreshold.setText("50"); } } }); @@ -140,16 +143,38 @@ public void stateChanged(ChangeEvent arg0) { if(radBntText.isSelected()){ combMethod.setEnabled(false); //ֹ㷨ѡť combLang.setEnabled(false); + txtThreshold.setText("50"); } } }); - radBntText.setBounds(158, 26, 98, 23); + radBntText.setBounds(106, 26, 98, 23); ButtonGroup rbGroup = new ButtonGroup(); rbGroup.add(radBntProgram); rbGroup.add(radBntText); panel.add(radBntText); + radBntImage = new JRadioButton("\u56FE\u7247"); + radBntImage.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + //ͼƬťѡ + if(radBntImage.isSelected()){ + combMethod.setEnabled(false); //ֹ㷨ѡť + combLang.setEnabled(false); + txtThreshold.setText("80"); + } + } + + }); + radBntImage.setToolTipText("\u652F\u6301\u56FE\u7247\u7C7B\u578B\uFF1Apng jpeg gif"); + radBntImage.setBounds(201, 26, 98, 23); + panel.add(radBntImage); + + ButtonGroup g1=new ButtonGroup(); + g1.add(radBntProgram); + g1.add(radBntText); + g1.add(radBntImage); + JPanel panel_1 = new JPanel(); panel_1.setBorder(new TitledBorder(null, "\u53C2\u6570", TitledBorder.LEADING, TitledBorder.TOP, null, null)); panel_1.setBounds(51, 181, 305, 95); @@ -256,7 +281,16 @@ public void actionPerformed(ActionEvent arg0) { }else if(res>0){ JOptionPane.showMessageDialog(PlagGUI.this, "ִϣδֵַҪĽԳԵƶֵ"); } - } + }else if(radBntImage.isSelected()){ //ȽͼƬ + String[] args = new String[2]; + args[0] = path; + args[1] = threshold; + ImageSim.main(args) ; // ִбȽ + JOptionPane.showMessageDialog(PlagGUI.this, "ִϣ鿴\r\nΪգԳԵƶֵ"); + + + + } }else{ diff --git a/src/imghash/plag/edu/ImageSim.java b/src/imghash/plag/edu/ImageSim.java new file mode 100644 index 0000000..e5b198f --- /dev/null +++ b/src/imghash/plag/edu/ImageSim.java @@ -0,0 +1,180 @@ +package imghash.plag.edu; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.github.kilianB.hash.Hash; +import com.github.kilianB.hashAlgorithms.HashingAlgorithm; +import com.github.kilianB.hashAlgorithms.PerceptiveHash; +import com.github.kilianB.hashAlgorithms.RotPHash; + +import data.plag.edu.SimData; +import utils.edu.FileIO; + +public class ImageSim { + String dic = null; //ҵ· + float threshold = 0.8f; //ͼƬĬ0.8 + List filels = new ArrayList(); //ҪȽϵļ + List listsd = new ArrayList(); //ļȽϵĽ + + //Ŀ¼µķչҪļĿ¼µģȡ + public void explore(File file) { + if (file != null && file.isDirectory()) { + File[] files = file.listFiles(new Fileter()); + for (File tempfile : files) { + if (tempfile.isDirectory()) { + explore(tempfile);// Ŀ¼ݹ + } else { + filels.add(tempfile); + + } + } + + } + } + + // ʵļ˽ӿڣڲ෽ʽ,ָֻչļĿ¼ + class Fileter implements FileFilter { + @Override + public boolean accept(File arg0) { + // TODO Auto-generated method stub + String fn = arg0.getName().toLowerCase(); + if (fn.endsWith(".png") // + || fn.endsWith(".jpg") + || fn.endsWith(".jpeg") + || fn.endsWith(".gif") + || fn.endsWith(".bmp") + || fn.endsWith(".tiff") + || arg0.isDirectory()) + return true; + return false; + } + } + + + + //ȽָĿ¼µͼƬļƶȣسֵָļ + void ImageSimFiles(float threshold){ + List listhashs = new ArrayList(); + HashingAlgorithm hasher = new PerceptiveHash(128); //128λphash + // HashingAlgorithm hasher = new RotPHash(256); //жתͼƬ + //ȶȡͼƬļhashֵ + for(int i=0;i=0;i--){ //ɴС + System.out.println(listsd.get(i).getSimilar()+" "+listsd.get(i).getFile1() + +" "+listsd.get(i).getFile2()); + } + } + + + + + //вɹ0ʧ-1 + int setParams(String[] args){ + int res = 0; + if(args.length<2){ + System.out.println("usage:"+"java -jar ImageSim.jar dic threshold"); + return -1; + } + this.dic = args[0]; + File dic = new File(this.dic); + if(!dic.isDirectory()){ + System.out.println("dic is not exsit!"); + return -1; + } + try { + this.threshold = Float.valueOf(args[1]); + if(this.threshold<0 || this.threshold>100){ + System.out.println("threshold is outof 0-100"); + return -1; + } + + } catch (NumberFormatException e) { + // TODO Auto-generated catch block + System.out.println("threshold is 0-100 number"); + return -1; + } + return res; + + } + /** + * @param args + */ + public static void main(String[] args) { + + try { + ImageSim testsc = new ImageSim(); + + int res = testsc.setParams(args); + if(res>=0){ + long st = System.currentTimeMillis(); + File file = new File(testsc.dic); + + testsc.explore(file); //ȡͼƬļhashֵ + + testsc.ImageSimFiles(testsc.threshold); //hashֵȽֵ + + testsc.report(); //ɽ + + File outfile = new File("out.txt"); + FileIO.saveFile(outfile, testsc.listsd,2,"from fh"); //ɴСŵ + + System.out.println("handle documents:"+testsc.filels.size()); + System.out.println("time:"+(System.currentTimeMillis()-st)); + }else{ + System.out.println(""); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + } + + +} diff --git a/src/shingle/plag/edu/ShingleSim.java b/src/shingle/plag/edu/ShingleSim.java index 9a283f7..b83d96f 100644 --- a/src/shingle/plag/edu/ShingleSim.java +++ b/src/shingle/plag/edu/ShingleSim.java @@ -184,7 +184,7 @@ public static void main(String[] args) { File outfile = new File("out.txt"); FileIO.saveFile(outfile, testsc.listsd,2,"from fh"); //Сŵ - System.out.println("handle documents:"+testsc.listsd.size()); + System.out.println("handle documents:"+testsc.filels.size()); System.out.println("time:"+(System.currentTimeMillis()-st)); }else{ System.out.println(""); diff --git a/testdata/doccn/heliwen_2.doc b/testdata/doccn/heliwen_2.doc deleted file mode 100644 index e9c3c39..0000000 Binary files a/testdata/doccn/heliwen_2.doc and /dev/null differ diff --git a/testdata/doccn/jiangMing_2.doc b/testdata/doccn/jiangMing_2.doc deleted file mode 100644 index c673868..0000000 Binary files a/testdata/doccn/jiangMing_2.doc and /dev/null differ diff --git a/testdata/doccn/luxiang-2.doc b/testdata/doccn/luxiang-2.doc deleted file mode 100644 index 5bb16df..0000000 Binary files a/testdata/doccn/luxiang-2.doc and /dev/null differ diff --git "a/testdata/doccn/makai\342\200\2242.doc" "b/testdata/doccn/makai\342\200\2242.doc" deleted file mode 100644 index d0d89d3..0000000 Binary files "a/testdata/doccn/makai\342\200\2242.doc" and /dev/null differ diff --git a/testdata/doccn/wangchen-2.doc b/testdata/doccn/wangchen-2.doc deleted file mode 100644 index 4d66147..0000000 Binary files a/testdata/doccn/wangchen-2.doc and /dev/null differ diff --git a/testdata/doccn/xiaqi_2.doc b/testdata/doccn/xiaqi_2.doc deleted file mode 100644 index 64605ff..0000000 Binary files a/testdata/doccn/xiaqi_2.doc and /dev/null differ diff --git a/testdata/doccn/xuzhiwen_2.doc b/testdata/doccn/xuzhiwen_2.doc deleted file mode 100644 index 98eafed..0000000 Binary files a/testdata/doccn/xuzhiwen_2.doc and /dev/null differ diff --git a/testdata/imgs/Lenna.png b/testdata/imgs/Lenna.png new file mode 100644 index 0000000..c2c9a13 Binary files /dev/null and b/testdata/imgs/Lenna.png differ diff --git a/testdata/imgs/Lenna90.png b/testdata/imgs/Lenna90.png new file mode 100644 index 0000000..0239ce0 Binary files /dev/null and b/testdata/imgs/Lenna90.png differ diff --git a/testdata/imgs/LennaSaltAndPepper.png b/testdata/imgs/LennaSaltAndPepper.png new file mode 100644 index 0000000..0377e91 Binary files /dev/null and b/testdata/imgs/LennaSaltAndPepper.png differ diff --git a/testdata/imgs/ballon.bmp b/testdata/imgs/ballon.bmp new file mode 100644 index 0000000..dccf02e Binary files /dev/null and b/testdata/imgs/ballon.bmp differ diff --git a/testdata/imgs/ballon.gif b/testdata/imgs/ballon.gif new file mode 100644 index 0000000..0a66181 Binary files /dev/null and b/testdata/imgs/ballon.gif differ diff --git a/testdata/imgs/ballon.jpg b/testdata/imgs/ballon.jpg new file mode 100644 index 0000000..be810ad Binary files /dev/null and b/testdata/imgs/ballon.jpg differ diff --git a/testdata/imgs/copyright.jpg b/testdata/imgs/copyright.jpg new file mode 100644 index 0000000..7332276 Binary files /dev/null and b/testdata/imgs/copyright.jpg differ diff --git a/testdata/imgs/high.jpg b/testdata/imgs/high.jpg new file mode 100644 index 0000000..d0e0594 Binary files /dev/null and b/testdata/imgs/high.jpg differ diff --git a/testdata/imgs/highQualityDark.png b/testdata/imgs/highQualityDark.png new file mode 100644 index 0000000..41b181b Binary files /dev/null and b/testdata/imgs/highQualityDark.png differ diff --git a/testdata/imgs/ks1.PNG b/testdata/imgs/ks1.PNG new file mode 100644 index 0000000..2e80ac1 Binary files /dev/null and b/testdata/imgs/ks1.PNG differ diff --git a/testdata/imgs/ks2.PNG b/testdata/imgs/ks2.PNG new file mode 100644 index 0000000..d888cfb Binary files /dev/null and b/testdata/imgs/ks2.PNG differ diff --git a/testdata/imgs/ks3.PNG b/testdata/imgs/ks3.PNG new file mode 100644 index 0000000..10795d4 Binary files /dev/null and b/testdata/imgs/ks3.PNG differ diff --git a/testdata/imgs/t3.png b/testdata/imgs/t3.png new file mode 100644 index 0000000..fce7536 Binary files /dev/null and b/testdata/imgs/t3.png differ diff --git a/testdata/imgs/t4.png b/testdata/imgs/t4.png new file mode 100644 index 0000000..9c875e3 Binary files /dev/null and b/testdata/imgs/t4.png differ diff --git a/testdata/imgs/thumbnail.jpg b/testdata/imgs/thumbnail.jpg new file mode 100644 index 0000000..f2d2b11 Binary files /dev/null and b/testdata/imgs/thumbnail.jpg differ