`
SpaceCity
  • 浏览: 97606 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

普通png图片解析(设计模式之模板模式)

阅读更多
package com.xxx.parse;

/**
* 图片解析接口
*
* @author XXX
*/
public interface ImgParser
{
    /**
     * @param priceUrl 图片路径
     * @return 图片上的价格
     */
    public String getImgText(String priceUrl);

}

package com.xxx.parse.imgparser;

import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import com.xxx.parse.ImgParser;

/**
* 图片价格解析(模板模式)
*
* @author XXX
*/
public abstract class AbstractPngImgParser implements ImgParser
{
    static
    {
        System.setProperty("com.sun.media.jai.disableMediaLib", "true");
    }

    @Override
    public String getImgText(String priceUrl)
    {
        StringBuilder price = new StringBuilder("暂无报价");

        // 图片上的数字
        if (null == priceUrl || "".equals(priceUrl.trim()))
        {
            return price.toString();
        }

        try
        {
            // 获取图片
            URL imgUrl = new URL(priceUrl);
            BufferedImage priceImage = ImageIO.read(imgUrl);

            // 若图片为空,则返回空
            if (null == priceImage)
            {
                return price.toString();
            }
            // 将价格图片分割的数量
            int num = getCount(priceImage);
            if (-1 == num)
            {
                return price.toString();
            }
            // 分割的小图片
            BufferedImage[] priceChars = new BufferedImage[num];
            // 开始切割的X像素
            int startX = getStartX();
            // 开始切割的Y像素
            int startY = getStartY();
            // 字符的宽度
            int width = getWidth();
            // 字符的高度
            int height = getHeight();
            // 清空价格字符串
            price.delete(0, price.length());
            for (int i = 0; i < num; i++)
            {
                // 切割图片
                priceChars[i] = priceImage.getSubimage(startX + i * width, startY, width, height);
                // 获取图片上单个数字
                price.append(getPriceNum(priceChars[i]));

            }
        }
        catch (Exception e)
        {
            return price.toString();
        }
        return price.toString();
    }

    /**
     * 解析单个图片
     *
     * @param priceImage 单个数字图片
     * @return 图片上的数字
     */
    private int getPriceNum(BufferedImage priceImage)
    {
        int priceNum = -1;
        if (null == priceImage)
        {
            return priceNum;
        }

        // 因为是二值图像,这里的方法将像素读取出来的同时,转换为0,1的图像数组。
        int width = priceImage.getWidth(null);
        int height = priceImage.getHeight(null);
        int[] pix = new int[width * height];
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                pix[i * (width) + j] = priceImage.getRGB(j, i);
                if (pix[i * (width) + j] == -1)
                {
                    pix[i * (width) + j] = 0;
                }
                else
                {
                    pix[i * (width) + j] = 1;
                }
            }
        }

        // 模板数组 0-9
        int[][] templetNum = getTempletNum();

        // 将图像数组与模板数字 0-9匹配,获取误差最小的一个数字
        int errorMaxValue = 100;
        for (int target = 0; target <= 9; target++)
        {
            int errorValue = 0;
            for (int i = 0; i < pix.length; i++)
            {
                errorValue += Math.abs(pix[i] - templetNum[target][i]);
            }
            if (errorValue == 0)
            {
                priceNum = target;
                break;
            }
            else if (errorValue < errorMaxValue)
            {
                errorMaxValue = errorValue;
                priceNum = target;
            }
        }

        return priceNum;
    }

    /**
     * @param image 价格图片
     * @return 图片上数字的有效位数
     */
    protected abstract int getCount(BufferedImage image);

    /**
     * @return 图片的数字0~9对应的模板数组
     */
    protected abstract int[][] getTempletNum();

    /**
     * @return 图片X轴的开始像素
     */
    protected abstract int getStartX();

    /**
     * @return 图片X轴的开始像素
     */
    protected abstract int getStartY();

    /**
     * @return 图片字符的宽度
     */
    protected abstract int getWidth();

    /**
     * @return 图片字符的高度
     */
    protected abstract int getHeight();

}

package com.xxx.parse.imgparser;

import java.awt.image.BufferedImage;
import com.xxx.ImgConstant;

/**
* xx价格图片解析
*
* @author XXX
*/
public class XxxPngImgParser extends AbstractPngImgParser
{

    @Override
    public int getCount(BufferedImage image)
    {
        if (null == image)
        {
            return -1;
        }
        else if (image.getWidth() == 110)
        {
            return 5;
        }
        else if (image.getWidth() == 97)
        {
            return 4;
        }
        else if (image.getWidth() == 81)
        {
            return 3;
        }
        else if (image.getWidth() == 70)
        {
            return 2;
        }
        else if (image.getWidth() == 60)
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }

    @Override
    public int[][] getTempletNum()
    {
        return ImgConstant.XxxValue;
    }

    @Override
    public int getStartX()
    {
        return 19;
    }

    @Override
    public int getStartY()
    {
        return 0;
    }

    @Override
    public int getWidth()
    {
        return 11;
    }

    @Override
    public int getHeight()
    {
        return 22;
    }

}
分享到:
评论

相关推荐

    xheditor-1.1.14

    参数值:图片上传前限制的文件扩展名列表,默认为:jpg,jpeg,gif,png,建议与服务端扩展名检查列表一致 upFlashUrl:动画文件上传接收URL 参数值:接收用户上传的服务器端程序URL,默认留空为禁用上传功能,具体使用...

    JAVA上百实例源码以及开源项目

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    JAVA上百实例源码以及开源项目源代码

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    KODExplorer 芒果云-资源管理器

    - 图片懒加载、图片较多的情况下只加载首屏图片缩略图; - 编辑文件打开出错,自动关闭标签;文件打开20M限制(大于20M则不处理,浏览器会卡死) - 标签关闭提示:检测是否有未保存文件,文件修改实时修改是否修修改的...

    苹果8XPC和手机二合一完整版

    ****************************模板规范化管理 开始**************************** 每个模版要把所用的css,js,img,html按照相关规定,放到指定目录。 每个模版都可定义不同的样式,所以系统内置的功能的相关文件也...

    vcg(验证码控件)

    提供简单易用的设计时所见即所得的可视化设置方式,并且支持设计时验证码图像效果与特效属性设置的实时联动体现,极大地提高程序员的工作效率; 2. 对验证码图像的包括残影、打散、风化、旋转、斜变等多种图形...

    PHP和MySQL Web开发第4版pdf以及源码

    2.10.1 使用普通文件的几个问题 2.10.2 RDBMS是如何解决这些问题的 2.11 进一步学习 2.12 下一章 第3章 使用数组 3.1 什么是数组 3.2 数字索引数组 3.2.1 数字索引数组的初始化 3.2.2 访问数组的内容 ...

    PHP和MySQL WEB开发(第4版)

    2.10.1 使用普通文件的几个问题 2.10.2 RDBMS是如何解决这些问题的 2.11 进一步学习 2.12 下一章 第3章 使用数组 3.1 什么是数组 3.2 数字索引数组 3.2.1 数字索引数组的初始化 3.2.2 访问数组的内容 3.2.3 使用...

    PHP和MySQL Web开发第4版

    2.10.1 使用普通文件的几个问题 2.10.2 RDBMS是如何解决这些问题的 2.11 进一步学习 2.12 下一章 第3章 使用数组 3.1 什么是数组 3.2 数字索引数组 3.2.1 数字索引数组的初始化 3.2.2 访问数组的内容 ...

Global site tag (gtag.js) - Google Analytics