/// <summary> /// 画像内の文字を検索 /// </summary> /// <param name="bmp">画像</param> /// <param name="color">文字色</param> /// <returns>結果</returns> public static List<StringText> LetterSearch( Bitmap bmp, Color color ) { var colordata = new bool[bmp.Width, bmp.Height]; var spacedata = ""; for( var y = 0; y < FONT_HEIGHT; y++ ) { spacedata += "0"; } //扱いやすいbool型に for( var x = 0; x < bmp.Width; x++ ) { for( var y = 0; y < bmp.Height; y++ ) { if( bmp.GetPixel( x, y ) == color ) { colordata[x, y] = true; } else { colordata[x, y] = false; } } } //各行の文字の一番上と一番下の行を求める var stringLineList = new List<StringLine>(); { var upperSide = -1; for( var y = 0; y < bmp.Height; y++ ) { var flag = false; for( var x = 0; x < bmp.Width; x++ ) { if( colordata[x, y] ) { flag = true; break; } } if( upperSide == -1 && flag ) { upperSide = y; } if( upperSide != -1 && !flag ) { stringLineList.Add( new StringLine( upperSide, y-1 ) ); upperSide = -1; } if( upperSide != -1 && y == bmp.Height-1 ) { stringLineList.Add(new StringLine(upperSide,y)); } } } using( var font = new Font() ) { var result = new List<StringText>(); foreach( var stringLine in stringLineList ) { var stringText = new StringText( 0, 0, "" ); foreach( var padding in stringLine.padding ) { //文字と文字の間の位置を求める var spaceList = new List<int>(); spaceList.Add(-1); for( var x = 0; x < bmp.Width; x++ ) { var flag = false; for( var y = stringLine.upperSide; y <= stringLine.lowerSide; y++ ) { if( colordata[x, y] ) { flag = true; break; } } if( !flag ) { spaceList.Add( x ); } } //0と1で構成されたfontdataを生成する var fontdataList = new List<string>(); for( var i = 0; i < spaceList.Count; i++ ) { var nextCol = i + 1 == spaceList.Count ? bmp.Width : spaceList[i + 1]; fontdataList.Add( spacedata ); if( spaceList[i] + 1 < nextCol ) { //次の行がスペースでない場合 if( stringText.x == 0 ) { stringText.x = spaceList[i] + 1; } var fontdata = ""; for( var x = spaceList[i] + 1; x < nextCol; x++ ) { for( var p = 0; p < padding.upper; p++ ) { fontdata += "0"; } for( var y = stringLine.upperSide; y <= stringLine.lowerSide; y++ ) { fontdata += colordata[x, y] ? "1" : "0"; } for( var p = 0; p < padding.lower; p++ ) { fontdata += "0"; } } fontdataList.Add( fontdata ); } } var tempStr = ""; for( var i = 0; i < fontdataList.Count; i++ ) { if( fontdataList.Count - 4 > i ) { if( fontdataList[i] == spacedata && fontdataList[i + 1] == spacedata && fontdataList[i + 2] == spacedata && fontdataList[i + 3] == spacedata ) { tempStr += " "; i += 3; continue; } } var res = font.LikeSearch( fontdataList[i] ); switch( res.Length ) { case 0: //該当0 break; case 1: tempStr += res[0][0]; break; default: //複数結果があった場合の処理 tempStr += LongestMatch( res, fontdataList.ToArray(), ref i ); break; } } tempStr = Regex.Replace( tempStr, "^ +| +$", "" ); if( stringText.text.Length < tempStr.Length ) { stringText.text = tempStr; stringText.y = stringLine.upperSide - padding.upper; } } result.Add( stringText ); } return result.ToList(); } }