Java实现抠图片文字或签名的完整代码

目录
  • java抠图片文字或签名
    • 运行原理
    • 完整代码

java抠图片文字或签名

运行原理

第一步 遍历像素点

BufferedImage image = ImageIO.read(new File(input));
// 图片透明度
int alpha = 0;
// 最小
int maxX = 0, maxY = 0;
// 最大
int minX = image.getWidth(), minY = image.getHeight();

for (int y = image.getMinY(); y < image.getHeight(); y++) {
// 内层遍历是X轴的像素
for (int x = image.getMinX(); x < image.getWidth(); x++) {
int rgb = image.getRGB(x, y);
// 对当前颜色判断是否在指定区间内
if (!colorInRange(rgb)) {
minX = minX > x ? x : minX;
minY = minY > y ? y : minY;
maxX = maxX < x ? x : maxX;
maxY = maxY < y ? y : maxY;
}
}
}

第二步 判断像素是否是黑色或者指定颜色

// 判断是背景还是内容
public static boolean colorInRange(int color) {
// 获取color(RGB)中R位
int red = (color & 0xff0000) >> 16;
// 获取color(RGB)中G位
int green = (color & 0x00ff00) >> 8;
// 获取color(RGB)中B位
int blue = (color & 0x0000ff);
// 通过RGB三分量来判断当前颜色是否在指定的颜色区间内
if (red >= color_range && green >= color_range && blue >= color_range) {
return true;
}
return false;
}

第三步 统计 选取图像的像素点最小坐标或最大坐标

minX = minX > x ? x : minX;
minY = minY > y ? y : minY;
maxX = maxX < x ? x : maxX;
maxY = maxY < y ? y : maxY;

第四步 新建画布(长度和高度=最大像素点-最小像素点)

BufferedImage bufferedImage = new BufferedImage(maxX - minX, maxY - minY, BufferedImage.TYPE_4BYTE_ABGR);

第五步 画图

for (int x = bufferedImage.getMinX(); x < bufferedImage.getWidth(); x++) {
// 内层遍历是X轴的像素
for (int y = bufferedImage.getMinX(); y < bufferedImage.getHeight(); y++) {
int rgb = image.getRGB(x + minX, y + minY);
if (!colorInRange(rgb)) {
// 设置为不透明
alpha = 255;
// #AARRGGBB 最前两位为透明度
rgb = (alpha << 24) | (0x000000);//黑色构图
bufferedImage.setRGB(x, y, rgb);
}
}
}

// 生成图片为PNG
ImageIO.write(bufferedImage, "png", new File(output));
// 输出图片坐标
System.out.println(minX + " " + minY + " " + maxX + " " + maxY);

完整代码

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Main {
    //识别颜色度数
    public static int color_range = 100;

    public static void recognize(String input, String output) throws IOException {
        BufferedImage image = ImageIO.read(new File(input));
        // 图片透明度
        int alpha = 0;
        // 最小
        int maxX = 0, maxY = 0;
        // 最大
        int minX = image.getWidth(), minY = image.getHeight();

        for (int y = image.getMinY(); y < image.getHeight(); y++) {
            // 内层遍历是X轴的像素
            for (int x = image.getMinX(); x < image.getWidth(); x++) {
                int rgb = image.getRGB(x, y);
                // 对当前颜色判断是否在指定区间内
                if (!colorInRange(rgb)) {
                    minX = minX > x ? x : minX;
                    minY = minY > y ? y : minY;
                    maxX = maxX < x ? x : maxX;
                    maxY = maxY < y ? y : maxY;
                }

            }
        }
        BufferedImage bufferedImage = new BufferedImage(maxX - minX, maxY - minY, BufferedImage.TYPE_4BYTE_ABGR);
        for (int x = bufferedImage.getMinX(); x < bufferedImage.getWidth(); x++) {
            // 内层遍历是X轴的像素
            for (int y = bufferedImage.getMinX(); y < bufferedImage.getHeight(); y++) {
                int rgb = image.getRGB(x + minX, y + minY);
                if (!colorInRange(rgb)) {
                    // 设置为不透明
                    alpha = 255;
                    // #AARRGGBB 最前两位为透明度
                    rgb = (alpha << 24) | (0x000000);//黑色构图
                    bufferedImage.setRGB(x, y, rgb);
                }
            }
        }

        // 生成图片为PNG
        ImageIO.write(bufferedImage, "png", new File(output));
        // 输出图片坐标
        System.out.println(minX + " " + minY + " " + maxX + " " + maxY);
    }

    // 判断是背景还是内容
    public static boolean colorInRange(int color) {
        // 获取color(RGB)中R位
        int red = (color & 0xff0000) >> 16;
        // 获取color(RGB)中G位
        int green = (color & 0x00ff00) >> 8;
        // 获取color(RGB)中B位
        int blue = (color & 0x0000ff);
        // 通过RGB三分量来判断当前颜色是否在指定的颜色区间内
        if (red >= color_range && green >= color_range && blue >= color_range) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) throws IOException {
        recognize("E:/tmp/demo1.jpg","E:/tmp/demo1_1.jpg");
    }
}

到此这篇关于java抠图片文字或签名的文章就介绍到这了,更多相关java抠图签名内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2022-06-22

Java 方法签名详解及实例代码

java 方法签名,我想做java 开发的朋友也知道,方法签名的重要性,是方法重载的一个比较好的解释,尤其是在后续优化方面,这里记录下,有看到的朋友也可看下, 方法签名的意义 对于同名不同类.同类不同名的方法,方法签名的意义并不是很大,但是对于重载方法来说,方法签名的意义就十分巨大了.由于重载方法之间的方法名是相同的,那么我们势必要从构成方法的其他几个要素中找到另一个要素与方法名组成能够唯一标示方法的签名,方法体当然不予考虑.那么就是形参列表和返回值了,但是由于对于调用方法的人来说,方法的形参数

Java加密和数字签名编程

本文主要谈一下密码学中的加密和数字签名,以及其在java中如何进行使用.对密码学有兴趣的伙伴,推荐看Bruce Schneier的著作:Applied Crypotography.在jdk1.5的发行版本中安全性方面有了很大的改进,也提供了对RSA算法的直接支持,现在我们从实例入手解决问题(本文仅是作为简单介绍): 一.密码学上常用的概念 1)消息摘要: 这是一种与消息认证码结合使用以确保消息完整性的技术.主要使用单向散列函数算法,可用于检验消息的完整性,和通过散列密码直接以文本形式保存等,目前

Java方法签名的获取实例代码

本文研究的主要是Java方法签名的获取,下面是具体实现实例. 实例代码: package com.yunshouhu; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Collection; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.

基于微信签名signature获取(实例讲解)

微信分享的签名算法微信也写有,主要是调用接口需要使用服务器(微信官方文档是这么说的,试了下前端居然特么也可以),不过微信的access_token和jsapi_ticket是有使用次数限制的,所以还是用服务器来获取,得到以后存下来,下次使用判断超时以后再重新获取,这样就够用了,要不然就会出现接口调用次数超出限制这种尴尬的事情了. 如果需要使用自定义分享文案的时候,服务号或者订阅号一定要是已认证的(我的是个人类型的订阅号,不能认证,所以不能使用分享功能) 我这边用的是node做的后台,所以代码用的

Java构建树形菜单的实例代码(支持多级菜单)

效果图:支持多级菜单. 菜单实体类: public class Menu { // 菜单id private String id; // 菜单名称 private String name; // 父菜单id private String parentId; // 菜单url private String url; // 菜单图标 private String icon; // 菜单顺序 private int order; // 子菜单 private List<Menu> children;

java 根据坐标截取图片实例代码

java 根据坐标截取图片 实例代码:代码中有不是注释,很好看懂! package com.json.test; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Iterator; import javax.imageio.

java随机验证码生成实现实例代码

java随机验证码生成实现实例代码 摘要: 在项目中有很多情况下都需要使用到随机验证码,这里提供一个java的随机验证码生成方案,可以指定难度,生成的验证码可以很方便的和其他组件搭配 之前要使用一个生成随机验证码的功能,在网上找了一下,有很多的人提出了不同的解决方案,但是很多人都使用了com.sun.image.这个包或者子包里面的类,而这个包结构下面的类都是不推荐使用的,我们应该依赖于java.或者javax.这些包结构下面的类,否则将来的可移植性就很不好(比如换成IBM的JDK就不行了),但

HDFS的Java API的访问方式实例代码

本文研究的主要是HDFS的Java API的访问方式,具体代码如下所示,有详细注释. 最近的节奏有点儿快,等有空的时候把这个封装一下 实现代码 要导入的包: import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.BlockLocation

java token生成和校验的实例代码

现在越来越多的登录方式都用到了token作为用户登录令牌,所以实现了一个token生成和校验案例. 缺点:该实现方式token是存储在内存中,不适合分布式项目,如需改为分布式项目部署,可把token存储在redis中,其中的实现原理还是保持不变. 一)token编码工具类 package com.oysept.token.utils; /** * token编码工具类 * @author ouyangjun */ public class TokenEncryptUtils { // 编码密码,

Java实现FTP服务器功能实例代码

FTP(File Transfer Protocol 文件传输协议)是Internet 上用来传送文件的协议.在Internet上通过FTP 服务器可以进行文件的上传(Upload)或下载(Download).FTP是实时联机服务,在使用它之前必须是具有该服务的一个用户(用户名和口令),工作时客户端必须先登录到作为服务器一方的计算机上,用户登录后可以进行文件搜索和文件传送等有关操作,如改变当前工作目录.列文件目录.设置传输参数及传送文件等.使用FTP可以传送所有类型的文件,如文本文件.二进制可执

JAVA用户自定义事件监听实例代码

JAVA用户自定义事件监听实例代码 很多介绍用户自定义事件都没有例子,或是例子不全,下面写了一个完整的例子,并写入了注释以便参考,完整的实例源代码如下: package demo; import Java.util.EventObject; /** * Title: 事件处理类,继承了事件基类 * Description: * Copyright: Copyright (c) 2005 * Company: cuijiang * @author not attributable * @versi