迁移内网代码的思路、实践,阿里OCR的相关信息,以及腾讯OCR的相关信息及使用。

1 篇文章 0 订阅

1、问题背景

迁移内网代码,不可以通过U盘等进行数据传输。

2、解决思路

一开始想的是无非就是拍照片文字识别或者手敲。

但是代码太多了,手敲可以完成,但是时间上和精力上都太折磨了。

一开始用腾讯QQ的ctrl+alt+A的截图来进行文字识别,但是效果不好,很多代码里的大写字母识别出来都是小写字母。

然后在网上搜了搜相关的OCR产品,对比了一下腾讯、阿里、百度的OCR,(谷歌的OCR当时好像是网页打不开,就没细看,有兴趣的同学可以研究研究)

百度的好像没有免费额度,阿里的识别出来的代码会团在一块,没有格式,不分行,腾讯识别出来的有格式,只不过有一些像O,0,o,L,l,1这种字符容易识别错,不过整体来看效果还是很不错的,而且每人每个月有1000条免费识别额度,我用的是通用印刷体(高精度版),这个根据你实际使用情况,因为我要导出的代码里有中文注释,所以用了通用印刷体,如果没有中文或者很少的话,可以用他的英文识别,应该效果会更好一些。

3、迁移步骤

1、把需要迁移的代码都复制到了Typora的```java代码块内。(复制到哪都无所谓,我主要是为了拍照的时候能够不拍到其他无用的信息)

2、F11进入Typora的全屏模式,进行拍照。

3、把拍好的这些照片按顺序一块发到QQ的我的手机上,点击另存为,新建一个文件夹pic,存到pic中。

这些照片会自动按顺序编号。(试过使用微信的文件传输助手,但是是单张的图片,还要自己另存为,对比QQ太麻烦了。)
在这里插入图片描述

在这里插入图片描述

4、通过腾讯的API文档,拿到示例代码。

5、改造示例代码,进行OCR,将识别结果输出到控制台。

6、对比内网代码进行部分字符大小写识别有误等问题的修改,完成代码迁移。

4、改造后的代码:贴在文章最后。

这个demo只是单个文件的,我在代码里对图片进行了压缩,循环处理,并对一些识别容易出错的字符进行了判断,有相似需求的可以看看。(图片如果不压缩的话,拍出来的照片会比较大,腾讯的demo代码会报错,我压缩了3倍左右。)

图片参数url和base64我选择了base64.(尝试使用过url,图片不是存储在腾讯云,用的本地的图片,然后通过花生壳进行内网穿透,填的内网穿透之后的那个url地址,但是不好用,所以最终选择base64.)
在这里插入图片描述
在这里插入图片描述

示例代码中的SecretId,SecretKey参数的值。

点击获取密钥,新建密钥就行了。把这个SecretId和SecretKey放到腾讯那个示例demo里就可以了。
在这里插入图片描述

腾讯文字识别计费的参考文档

在这里插入图片描述

腾讯OCR

在这里插入图片描述

接口调用统计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

阿里OCR
在这里插入图片描述

刚才又去阿里网站看了一下发现有这个全文识别高精版,这个可以成行返回,就是不知道对代码的识别程度怎么样,感兴趣的话可以试试。
在这里插入图片描述

阿里的是200次一个月。和腾讯的区别是,腾讯那个是好几种识别服务共用每月1000次免费额度,也可以某个服务用1000次,阿里的这个是某个服务最多200次一个月。

在这里插入图片描述

代码。

package com.tencent;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.GeneralAccurateOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.GeneralAccurateOCRResponse;
import com.tencentcloudapi.ocr.v20181119.models.TextDetection;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Base64;

public class GeneralAccurateOCR {

    /**
     * 第一次运行之前需要修改的参数如下。
     * 1、SecretId,SecretKey.
     * 2、OcrClient client = new OcrClient(cred, "ap-beijing", clientProfile);根据自己所在区域选择不同的region参数也就是"ap-beijing"
     * <p>
     * 每次运行之前需要修改的参数如下。
     * 1、for循环的i值,根据实际情况修改起始值和终止值大小。
     * 2、修改图片存储路径 savePicPath 和压缩之后输出的路径 compressPicOutPath,压缩之后输出的路径要和图片OCR的路径一致。
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
        // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
        // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
        Credential cred = new Credential("SecretId", "SecretKey");
        // 实例化一个http选项,可选的,没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("ocr.tencentcloudapi.com");
        // 实例化一个client选项,可选的,没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        OcrClient client = new OcrClient(cred, "ap-beijing", clientProfile);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        GeneralAccurateOCRRequest req = new GeneralAccurateOCRRequest();

        // 这里想把识别出来的这些代码写到一个文件中,但是不知道为啥不好用,也没仔细研究,
        // 因为输出到控制台对我来说效果一样,感兴趣可以研究研究。
        // 每个照片都往txt里写一段代码。
        String filePath = "path\\pic.txt";
        FileWriter writer = new FileWriter(filePath);
        for (int i = 2921; i <= 2938; i++) {
            // 图片压缩。
            // 存放拍照的图片路径
            String savePicPath = "path\\pic\\IMG_" + i + ".JPG";
            // 存放压缩后的图片路径,也就是准备OCR的图片路径。
            String compressPicOutPath = "path\\pic\\" + i + ".JPG";
            File sourceFile = new File(savePicPath);
            File destinationFile = new File(compressPicOutPath);
            float compressionQuality = 0.5f; // 压缩质量范围:0.0f - 1.0f
            try {
                compressImage(sourceFile, destinationFile, compressionQuality);
                System.out.println("第{" + i + "}张图片压缩成功");
            } catch (IOException e) {
                System.out.println("An error occurred while compressing the image: " + e.getMessage());
            }

            System.out.println("第{" + i + "}张图片开始OCR");
            String fileBase64 = getFileBase64(compressPicOutPath);
            req.setImageBase64(fileBase64);
            // 返回的resp是一个GeneralAccurateOCRResponse的实例,与请求对象对应
            GeneralAccurateOCRResponse resp = client.GeneralAccurateOCR(req);
            // 输出json格式的字符串回包
//            System.out.println(GeneralAccurateOCRResponse.toJsonString(resp));
            // 主要就是拿这个 DetectedText 字段的值。
            // {"TextDetections":[{"DetectedText":"@SLf4j","Confidence":100,"Polygon":[{"X":7,"Y":2},{"X":106,"Y":2},{"X":106,"Y":38},{"X":7,"Y":38}],
            // "AdvancedInfo":"{\"Parag\":{\"ParagNo\":1}}","ItemPolygon":{"X":7,"Y":2,"Width":100,"Height":37},"Words":[],"WordCoordPoint":[]},
            // {"DetectedText":"@Service","Confidence":100,"Polygon":[{"X":8,"Y":44},{"X":135,"Y":42},{"X":136,"Y":75},{"X":9,"Y":77}],
            // "AdvancedInfo":"{\"Parag\":{\"ParagNo\":2}}","ItemPolygon":{"X":8,"Y":42,"Width":129,"Height":36},"Words":[],"WordCoordPoint":[]},
            TextDetection[] textDetections = resp.getTextDetections();
            // 循环逐行写入txt该图片中的所有代码。
            for (TextDetection textDetection : textDetections) {
                String detectedText = textDetection.getDetectedText();
                // 这个前者可以在idea设置里把这个关了,后者就是鼠标光标的识别
                if ("no usages new*".equals(detectedText) || "I".equals(detectedText)) {
                    continue;
                }
                if (detectedText.contains("Log.")) {
                    detectedText = detectedText.replace("Log.", "log.");
                }
                if (detectedText.contains(",")) {
                    detectedText = detectedText.replace(",", ",");
                }
                // 这个具体看你代码场景决定是否使用。也就是0特别多还是O特别多。
//                if (detectedText.contains("0")) {
//                    detectedText = detectedText.replace("0", "O");
//                }
                if (detectedText.contains("@SLf4j")) {
                    detectedText = detectedText.replace("@SLf4j", "@Slf4j");
                }
                if (detectedText.contains("@slf4j")) {
                    detectedText = detectedText.replace("@slf4j", "@Slf4j");
                }
                if (detectedText.contains("@sTf4j")) {
                    detectedText = detectedText.replace("@sTf4j", "@Slf4j");
                }
                if (detectedText.contains("aResource")) {
                    detectedText = detectedText.replace("aResource", "@Resource");
                }
                if (detectedText.contains("aOverride")) {
                    detectedText = detectedText.replace("aOverride", "@Override");
                }
                if (detectedText.contains("ArnayList")) {
                    detectedText = detectedText.replace("ArnayList", "ArrayList");
                }
                if (detectedText.contains("tostring")) {
                    detectedText = detectedText.replace("tostring", "toString");
                }
                if (detectedText.contains("v2")) {
                    detectedText = detectedText.replace("v2", "V2");
                }
                if (detectedText.contains("setPagesize")) {
                    detectedText = detectedText.replace("setPagesize", "setPageSize");
                }
                if (detectedText.contains("Seryice.")) {
                    detectedText = detectedText.replace("Seryice.", "Service.");
                }
                if (detectedText.contains("GAutowired")) {
                    detectedText = detectedText.replace("GAutowired", "@Autowired");
                }

                System.out.println(detectedText);
                writer.write(detectedText + "\n");
            }
        }
    }

    /**
     * 获取文件的base64
     *
     * @param filePath
     * @return
     */
    public static String getFileBase64(String filePath) {
        File file = new File(filePath);
        try {
            // 将文件转换为字节数组
            byte[] fileBytes = readBytesFromFile(file);
            // 对字节数组进行Base64编码
            String base64Data = Base64.getEncoder().encodeToString(fileBytes);
//            System.out.println(base64Data);
            return base64Data;
            // 在这里可以进行后续的操作,如发送Base64数据到服务器等
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static byte[] readBytesFromFile(File file) throws IOException {
        FileInputStream fis = null;
        byte[] fileBytes;
        try {
            fis = new FileInputStream(file);
            fileBytes = new byte[(int) file.length()];
            fis.read(fileBytes);
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
        return fileBytes;
    }

    /**
     * 图片压缩
     *
     * @param sourceFile
     * @param destinationFile
     * @param compressionQuality
     * @throws IOException
     */
    public static void compressImage(File sourceFile, File destinationFile, float compressionQuality) throws IOException {
        BufferedImage image = ImageIO.read(sourceFile);

        // 获取JPEG图像写入器
        ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();

        // 创建图像写入参数并设置压缩质量
        JPEGImageWriteParam writeParam = new JPEGImageWriteParam(null);
        writeParam.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionQuality(compressionQuality);

        // 创建图像输出流并指定目标文件
        ImageOutputStream outputStream = ImageIO.createImageOutputStream(destinationFile);
        writer.setOutput(outputStream);

        // 写入图像并完成压缩
        writer.write(null, new javax.imageio.IIOImage(image, null, null), writeParam);
        writer.dispose();
        outputStream.close();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值