普通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;
    }

}

猜你喜欢

转载自spacecity.iteye.com/blog/1465250