2 a1364850760 a1364850760 于 2014.03.11 19:40 提问

运行时提示错误“不包含适合于入口点的静态“Main”方法”,怎么解决?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using System.Configuration;

namespace ConsoleApplication4
{
///
/// 根据样本做验证码破解
///
/// 需要在.config文件中的appSettings配置节中添加key为sampleOcr.sampleDir value设置为样本图片所在路径
/// 验证码:https://investorservice.cfmmc.com/ https://investorservice.cfmmc.com/veriCode.do?t=1335521167762&ip=202.99.16.22
///
/// outofmemory.cn 20120427
/// 100个样例准确数为88个,错误主要发生在389这三个字符的混淆上
///
public abstract class SampleOcr
{
///
/// 灰度中间值
///
static int MiddleGrayValue = 200;

    /// <summary>
    /// 分割图片的差异容忍度
    /// </summary>
    static int ColorToleranceForSplit = 30;

    /// <summary>
    /// 样本字典
    /// </summary>
    static Dictionary<string, Bitmap> _samples;

    /// <summary>
    /// 破解验证码
    /// </summary>
    /// <param name="bm">验证码图片</param>
    /// <returns>验证码文本</returns>
    public static string Ocr(Bitmap bm)
    {
        //做灰度处理
        GrayByPixels(bm);

        bm = RemoveVerticalSpaceRegion(bm);

        Bitmap[] splitBms = SplitBitmaps(bm);

        char[] result = new char[splitBms.Length];
        for (int i = 0; i < splitBms.Length; i++)
        {
            result[i] = OcrChar(splitBms[i]);
            splitBms[i].Dispose();
        }
        return new string(result);
    }

    /// <summary>
    /// 分割图片
    /// </summary>
    /// <param name="bm">图片</param>
    /// <returns>分割后的图片对象</returns>
    static Bitmap[] SplitBitmaps(Bitmap bm)
    {
        //找出垂直分割线
        List<int> removeXs = new List<int>();
        for (int x = 0; x < bm.Width; x++)
        {
            bool hasDiffPoint = false;
            Color color = Color.White;
            for (int y = 0; y < bm.Height; y++)
            {
                if (y == 0)
                {
                    color = bm.GetPixel(x, y);
                }
                else
                {
                    Color currentColor = bm.GetPixel(x, y);
                    int diff = CalculateColorDifference(currentColor, color);
                    if (diff > ColorToleranceForSplit)
                    {
                        hasDiffPoint = true;
                        break;
                    }
                    // color = currentColor;
                }
            }

            if (!hasDiffPoint)
            {
                removeXs.Add(x);
            }
        }

        //根据空白区域,计算各个字符的位图          
        List<Rectangle> charRects = new List<Rectangle>();
        for (int i = 1; i < removeXs.Count; i++)
        {
            int diff = removeXs[i] - removeXs[i - 1];
            if (diff > 5)
            {
                if (diff >= 20)
                {
                    Rectangle rect = new Rectangle(removeXs[i - 1], 0, diff / 2, bm.Height);
                    charRects.Add(rect);

                    rect = new Rectangle(removeXs[i - 1] + diff / 2, 0, diff / 2, bm.Height);
                    charRects.Add(rect);
                }
                else
                {
                    Rectangle rect = new Rectangle(removeXs[i - 1], 0, diff, bm.Height);
                    charRects.Add(rect);
                }
            }
        }

        int count = charRects.Count;
        Bitmap[] charBms = new Bitmap[count];
        int charBmIndex = 0;
        foreach (Rectangle item in charRects)
        {
            Bitmap bmChar = bm.Clone(item, bm.PixelFormat);
            charBms[charBmIndex] = bmChar;
            charBmIndex += 1;
        }
        return charBms;
    }

    /// <summary>
    /// 解析字符
    /// </summary>
    /// <param name="bm">分割后的小图</param>
    /// <returns>字符</returns>
    static char OcrChar(Bitmap bm)
    {
        Dictionary<string, Bitmap> samples = LoadSamples();

        double diff = .0;
        string mayBe = null;
        foreach (string key in samples.Keys)
        {
            double diffRate = CalcImageDiffRate(samples[key], bm);
            if (diffRate == 1)
                return key[0];

            if (diffRate > diff)
            {
                mayBe = key;
                diff = diffRate;
            }
        }

        if (mayBe == null) throw new ApplicationException();

        return mayBe[0];
    }

    /// <summary>
    /// 载入样本字典
    /// </summary>
    /// <returns>样本字典</returns>
    private static Dictionary<string, Bitmap> LoadSamples()
    {
        if (_samples == null)
        {
            _samples = new Dictionary<string, Bitmap>();
            string sampleDir = ConfigurationManager.AppSettings["sampleOcr.sampleDir"] ?? @"D:\SampleOcr\samples";
            DirectoryInfo dirInfo = new DirectoryInfo(sampleDir);
            FileInfo[] files = dirInfo.GetFiles("*.jpg");
            foreach (FileInfo item in files)
            {
                Bitmap bm = (Bitmap)Bitmap.FromFile(item.FullName);
                string key = Path.GetFileNameWithoutExtension(item.FullName);
                _samples.Add(key, bm);
            }
        }

        return _samples;
    }

    /// <summary>
    /// 根据RGB,计算灰度值
    /// </summary>
    /// <param name="posClr">Color值</param>
    /// <returns>灰度值,整型</returns>
    static int GetGrayNumColor(System.Drawing.Color posClr)
    {
        return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16;
    }

    /// <summary>
    /// 灰度转换,逐点方式
    /// </summary>
    static void GrayByPixels(Bitmap bm)
    {
        for (int i = 0; i < bm.Height; i++)
        {
            for (int j = 0; j < bm.Width; j++)
            {
                int tmpValue = GetGrayNumColor(bm.GetPixel(j, i));
                bm.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
            }
        }
    }

    /// <summary>
    /// 删除垂直方向上的空白区域
    /// </summary>
    /// <param name="bm">源图片</param>
    /// <returns>删除空白之后的图片</returns>
    static Bitmap RemoveVerticalSpaceRegion(Bitmap bm)
    {
        int topSpaceHeight = 0;
        for (int y = 0; y < bm.Height; y++)
        {
            bool hasDiffPoint = false;
            Color color = Color.White;
            for (int x = 0; x < bm.Width; x++)
            {
                if (x == 0)
                {
                    color = bm.GetPixel(x, y);
                }
                else
                {
                    Color currentColor = bm.GetPixel(x, y);
                    int diff = CalculateColorDifference(currentColor, color);
                    if (diff > ColorToleranceForSplit)
                    {
                        hasDiffPoint = true;
                        break;
                    }
                }
            }

            if (hasDiffPoint)
            {
                break;
            }
            else
            {
                topSpaceHeight += 1;
            }
        }

        int bottomSpaceHeight = 0;
        for (int y = bm.Height - 1; y > 0; y--)
        {
            bool hasDiffPoint = false;
            Color color = Color.White;
            for (int x = 0; x < bm.Width; x++)
            {
                if (x == 0)
                {
                    color = bm.GetPixel(x, y);
                }
                else
                {
                    Color currentColor = bm.GetPixel(x, y);
                    int diff = CalculateColorDifference(currentColor, color);
                    if (diff > ColorToleranceForSplit)
                    {
                        hasDiffPoint = true;
                        break;
                    }
                    color = currentColor;
                }
            }

            if (hasDiffPoint)
            {
                break;
            }
            else
            {
                bottomSpaceHeight += 1;
            }
        }

        Rectangle rectValid = new Rectangle(0, topSpaceHeight, bm.Width, bm.Height - topSpaceHeight - bottomSpaceHeight);
        Bitmap newBm = bm.Clone(rectValid, bm.PixelFormat);
        bm.Dispose();
        return newBm;
    }

    private static double CalcImageDiffRate(Bitmap bmSample, Bitmap bmCalc)
    {
        int[] eSample = new int[bmSample.Height];
        int[] eCalc = new int[bmSample.Height];
        for (int y = 0; y < bmSample.Height; y++)
        {
            eSample[y] = GetHorizontalValue(bmSample, y);
            eCalc[y] = GetHorizontalValue(bmCalc, y);
        }
        return GetCosine(eSample, eCalc);
    }

    /// <summary>
    /// 获得向量的cos值
    /// </summary>
    /// <param name="e1"></param>
    /// <param name="e2"></param>
    /// <returns></returns>
    static double GetCosine(int[] e1, int[] e2)
    {
        double fenzi = 0;
        for (int i = 0; i < e1.Length; i++)
        {
            fenzi += e1[i] * e2[i];
        }

        double fenmuLeft = 0;
        double fenmuRight = 0;
        for (int i = 0; i < e1.Length; i++)
        {
            fenmuLeft += e1[i] * e1[i];
            fenmuRight += e2[i] * e2[i];
        }

        double fenmu = Math.Sqrt(fenmuLeft) * Math.Sqrt(fenmuRight);
        if (fenmu == 0.0) return 0;

        return fenzi / fenmu;
    }

    /// <summary>
    /// 计算水平方向上的差异点数
    /// </summary>
    /// <param name="bm">位图</param>
    /// <param name="y">y坐标值</param>
    /// <returns>差异点数</returns>
    private static int GetHorizontalValue(Bitmap bm, int y)
    {
        if (y >= bm.Height) return 0;
        int val = 0;
        for (int x = 0; x < bm.Width; x++)
        {
            Color color = bm.GetPixel(x, y);

            int grayVal = GetColorGrayValue(color);
            if (grayVal > MiddleGrayValue)
            {
                val |= (1 << x);
            }
        }
        return val;
    }

    static int GetColorGrayValue(Color color)
    {
        return (int)(.299 * color.R + .587 * color.G + .114 * color.B);
    }

    /// <summary>
    /// 计算颜色之间的差值,这个只是一个简单的计算,真正的色差计算很复杂
    /// </summary>
    /// <param name="colorA">A色</param>
    /// <param name="colorB">B色</param>
    /// <returns>差值</returns>
    static int CalculateColorDifference(Color colorA, Color colorB)
    {
        int diff = GetColorGrayValue(colorA) - GetColorGrayValue(colorB);
        return Math.Abs(diff);
    }
}

}

1个回答

oyljerry
oyljerry   Ds   Rxr 2015.01.11 15:43

定义一个main函数

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!