【二十一】插件开发——用于验证码识别的 JMeter 插件(上)

目录

一、eclipse开发插件项目

二、lib目录jar包准备

三、src目录代码准备

四、导出为jar包


一、eclipse开发插件项目

(1)eclipse开发插件项目全部目录:

【二十一】插件开发——用于验证码识别的 JMeter 插件(上)_第1张图片


(2)完成插件直接在eclipse运行测试:

【二十一】插件开发——用于验证码识别的 JMeter 插件(上)_第2张图片



二、lib目录jar包准备

点击查看我的另一篇博文:【jmeter】实现验证码登录



三、src目录代码准备

(1)ImageIOHelper类:

主要包含两大部分,一部分就是降噪逻辑,通过创建降噪规则对背景图片像素点进行逐个扫描过滤,加大识别成功率;

另一部分是将图片格式转换为tiff格式以更好地进行识别,代码参考如下:


   
   
   
   
  1. package com.test.gss;
  2. import java.awt.Color;
  3. import java.awt.image.BufferedImage;
  4. import java.io.File;
  5. import java.io.IOException;
  6. import java.util.Iterator;
  7. import java.util.Locale;
  8. import javax.imageio.IIOImage;
  9. import javax.imageio.ImageIO;
  10. import javax.imageio.ImageReader;
  11. import javax.imageio.ImageWriteParam;
  12. import javax.imageio.ImageWriter;
  13. import javax.imageio.metadata.IIOMetadata;
  14. import javax.imageio.stream.ImageInputStream;
  15. import javax.imageio.stream.ImageOutputStream;
  16. import com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam;
  17. public class ImageIOHelper{
  18. //将图片格式转换为tif格式以更好地进行识别
  19. public static File createImage(File imageFile, String imageFormat) {
  20. File tempFile = null;
  21. ImageInputStream iis = null;
  22. ImageOutputStream ios = null;
  23. ImageReader reader = null;
  24. ImageWriter writer = null;
  25. try {
  26. Iterator readers = ImageIO.getImageReadersByFormatName(imageFormat);
  27. reader = readers.next();
  28. iis = ImageIO.createImageInputStream(imageFile);
  29. reader.setInput(iis);
  30. IIOMetadata streamMetadata = reader.getStreamMetadata();
  31. TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.CHINESE);
  32. tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
  33. Iterator writers = ImageIO.getImageWritersByFormatName( "tiff");
  34. writer = writers.next();
  35. BufferedImage bi = removeBackgroud(reader.read( 0));
  36. IIOImage image = new IIOImage(bi, null,reader.getImageMetadata( 0));
  37. tempFile = tempImageFile(imageFile);
  38. ios = ImageIO.createImageOutputStream(tempFile);
  39. writer.setOutput(ios);
  40. writer.write(streamMetadata, image, tiffWriteParam);
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. } catch (Exception e) {
  44. // TODO Auto-generated catch block
  45. e.printStackTrace();
  46. } finally {
  47. if(iis != null){
  48. try {
  49. iis.close();
  50. } catch (IOException e) {
  51. // TODO Auto-generated catch block
  52. e.printStackTrace();
  53. }
  54. }
  55. if(ios != null){
  56. try {
  57. ios.close();
  58. } catch (IOException e) {
  59. // TODO Auto-generated catch block
  60. e.printStackTrace();
  61. }
  62. }
  63. if(writer != null){
  64. writer.dispose();
  65. }
  66. if(reader != null){
  67. reader.dispose();
  68. }
  69. }
  70. return tempFile;
  71. }
  72. private static File tempImageFile(File imageFile) {
  73. String path = imageFile.getPath();
  74. StringBuffer strB = new StringBuffer(path);
  75. return new File(strB.toString().replaceFirst( "jpg", "tif"));
  76. }
  77. //给图片降噪,建立如下降噪规则和方法,提高识别度
  78. public static int isFilter(int colorInt) {
  79. Color color = new Color(colorInt);
  80. if ((color.getRed() > 85 && color.getRed() < 255)
  81. && (color.getGreen() > 85 && color.getGreen() < 255)
  82. && (color.getBlue() > 85 && color.getBlue() < 255)) {
  83. return 1;
  84. }
  85. return 0;
  86. }
  87. public static BufferedImage removeBackgroud(BufferedImage img)
  88. throws Exception {
  89. int width = img.getWidth();
  90. int height = img.getHeight();
  91. for ( int x = 0; x < width; ++x) {
  92. for ( int y = 0; y < height; ++y) {
  93. if (isFilter(img.getRGB(x, y)) == 1) {
  94. img.setRGB(x, y, Color.WHITE.getRGB());
  95. }
  96. }
  97. }
  98. return img;
  99. }
  100. }

(2)OCR类:

通过Process调用已经安装的Tesseract程序,调用命令基本形式为tesseract xxx.tif 1 -l eng,参考如下代码:


   
   
   
   
  1. package com.test.gss;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.IOException;
  6. import java.io.InputStreamReader;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. public class OCR {
  10. private final String LANG_OPTION = "-l";
  11. private final String EOL = System.getProperty( "line.separator");
  12. //第三方图形图像识别工具tesseract-OCR的安装目录
  13. private String tessPath = "G://Tesseract-ocr//tesserract//Tesseract-ORC//Tesseract-OCR";
  14. public String recognizeText(File imageFile,String imageFormat) {
  15. File tempImage = ImageIOHelper.createImage(imageFile,imageFormat);
  16. File outputFile = new File(imageFile.getParentFile(), "output" + imageFile.getName());
  17. StringBuffer sb = new StringBuffer();
  18. List cmd = new ArrayList();
  19. cmd.add(tessPath+ "//tesseract");
  20. cmd.add( "");
  21. cmd.add(outputFile.getName());
  22. cmd.add(LANG_OPTION);
  23. cmd.add( "eng");
  24. ProcessBuilder pb = new ProcessBuilder();
  25. pb.directory(imageFile.getParentFile());
  26. cmd.set( 1, tempImage.getName());
  27. pb.command(cmd);
  28. pb.redirectErrorStream( true);
  29. Process process = null;
  30. BufferedReader in = null;
  31. int wait;
  32. try {
  33. process = pb.start();
  34. //通过Process调用已经安装的Tesseract程序,调用命令基本形式为:tesseract xxx.tif 1 -l eng
  35. wait = process.waitFor();
  36. if(wait == 0){
  37. in = new BufferedReader( new InputStreamReader( new FileInputStream(outputFile.getAbsolutePath()+ ".txt"), "UTF-8"));
  38. String str;
  39. while((str = in.readLine())!= null){
  40. sb.append(str).append(EOL);
  41. }
  42. in.close();
  43. } else{
  44. tempImage.delete();
  45. }
  46. new File(outputFile.getAbsolutePath()+ ".txt").delete();
  47. } catch (IOException e) {
  48. // TODO Auto-generated catch block
  49. e.printStackTrace();
  50. } catch (InterruptedException e) {
  51. // TODO Auto-generated catch block
  52. e.printStackTrace();
  53. } finally {
  54. if(in != null){
  55. try {
  56. in.close();
  57. } catch (IOException e) {
  58. // TODO Auto-generated catch block
  59. e.printStackTrace();
  60. }
  61. }
  62. }
  63. tempImage.delete();
  64. return sb.toString();
  65. }
  66. }

(3)VcodeExtractor类:

继承AbstractScopedTestElement抽象类,实现PostProcessor接口的process方法,来处理利用OCR读取验证码信息的逻辑控制,参考代码如下:


   
   
   
   
  1. package com.test.gss;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.Serializable;
  6. import org.apache.jmeter.processor.PostProcessor;
  7. import org.apache.jmeter.samplers.SampleResult;
  8. import org.apache.jmeter.testelement.AbstractScopedTestElement;
  9. import org.apache.jmeter.threads.JMeterContext;
  10. import org.apache.jmeter.threads.JMeterVariables;
  11. import org.slf4j.Logger;
  12. import org.slf4j.LoggerFactory;
  13. public class VcodeExtractor extends AbstractScopedTestElement implements PostProcessor, Serializable{
  14. private static final long serialVersionUID = 1L;
  15. private static final Logger log = LoggerFactory.getLogger(VcodeExtractor.class);
  16. @Override
  17. public void process() {
  18. // TODO Auto-generated method stub
  19. JMeterContext context = getThreadContext();
  20. SampleResult previousResult = context.getPreviousResult();
  21. if (previousResult == null) {
  22. return;
  23. }
  24. log.debug( "VcodeExtractor processing result");
  25. String status = previousResult.getResponseCode();
  26. int id = context.getThreadNum();
  27. //String imageName = id + ".jpg";
  28. String path = "E://" + id + ".jpg";
  29. if(status.equals( "200")){
  30. byte[] buffer = previousResult.getResponseData();
  31. FileOutputStream out = null;
  32. File file = null;
  33. try {
  34. file = new File(path);
  35. out = new FileOutputStream(file);
  36. out.write(buffer);
  37. out.flush();
  38. } catch (IOException e) {
  39. // TODO Auto-generated catch block
  40. e.printStackTrace();
  41. } finally {
  42. if(out != null){
  43. try {
  44. out.close();
  45. } catch (IOException e) {
  46. // TODO Auto-generated catch block
  47. e.printStackTrace();
  48. }
  49. }
  50. }
  51. try {
  52. String vcode = new OCR().recognizeText(file, "jpeg");
  53. vcode = vcode.replace( " ", "").trim();
  54. JMeterVariables var = context.getVariables();
  55. var.put( "vcode", vcode);
  56. var.put( "vuser", String.valueOf(id));
  57. } catch (Exception e) {
  58. e.printStackTrace();
  59. }
  60. }
  61. }
  62. }

(4)VcodeExtractorGUI类:

单纯实现一个可视化的界面用于在测试计划Tree中进行操作,参照代码如下:


   
   
   
   
  1. package com.test.gss;
  2. import org.apache.jmeter.processor.gui.AbstractPostProcessorGui;
  3. import org.apache.jmeter.testelement.TestElement;
  4. public class VcodeExtractorGUI extends AbstractPostProcessorGui{
  5. private static final long serialVersionUID = 1L;
  6. @Override
  7. public TestElement createTestElement() {
  8. // TODO Auto-generated method stub
  9. VcodeExtractor extractor = new VcodeExtractor();
  10. modifyTestElement(extractor);
  11. return extractor;
  12. }
  13. @Override
  14. public String getLabelResource() {
  15. // TODO Auto-generated method stub
  16. return this.getClass().getName();
  17. }
  18. @Override
  19. public String getStaticLabel() {
  20. //设置显示名称
  21. // TODO Auto-generated method stub
  22. return "VcodeExtractor";
  23. }
  24. @Override
  25. public void modifyTestElement(TestElement extractor) {
  26. // TODO Auto-generated method stub
  27. super.configureTestElement(extractor);
  28. }
  29. }

(5)TestOCR类:

方便设置main程序启动入口:


   
   
   
   
  1. package com.test.gss;
  2. import java.io.File;
  3. public class TestOCR {
  4. public static void main(String[] args) {
  5. String path = "E://100.jpg";
  6. System.out.println( "ORC Test Begin......");
  7. try {
  8. String valCode = new OCR().recognizeText( new File(path), "jpeg");
  9. System.out.println(valCode);
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println( "ORC Test End......");
  14. }
  15. }


四、导出为jar包

【二十一】插件开发——用于验证码识别的 JMeter 插件(上)_第3张图片

【二十一】插件开发——用于验证码识别的 JMeter 插件(上)_第4张图片

【二十一】插件开发——用于验证码识别的 JMeter 插件(上)_第5张图片

【二十一】插件开发——用于验证码识别的 JMeter 插件(上)_第6张图片



五、插件下载

目前我开发好的插件,主要封装以上代码,但是目前不能直接使用,后期我会再研究优化,如需上面封装的代码,可到我的资源下载:点击前往下载

你可能感兴趣的:(jmeter)