0

Windows Server 2008R2 64bit (x86) がインストールされた開発用 PC を譲ってもらったので、ワークステーションとして使用しています。私の開発環境は、.NET3.5 をターゲットとする VS2008 です (YES, 2008 !!!)

私たちのウェブサイト (現在は数年前) には、社内で開発された Captcha があります。

簡単に言うと、文字は私の開発マシン 2008R2-64 では出力されませんが、他のすべてのウィンドウ (テスト サーバーとライブ サーバーは 2003 64 ビット) と Virtual PC (2008 32 ビット R2、XP、Win7 ではありません) では出力されます。

Web で、ピクセルの測定方法が変更された可能性がある (特定するのは難しい) という投稿を見たことがありますが、それ以外はあまり変わりません。

問題を説明するための小さな Web アプリケーションを次に示します。

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Captcha1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Random _randomNumberGenerator = new Random();

            /* Output random string */
            float _xPosition = 20;
            float _xPositionMax = 0;
            float _yPosition = 0;
            float _yPositionMax = 0;
            string strRandom = string.Empty;

            /* Prepare drawing functions to output */
            System.Drawing.Bitmap objBmp = new System.Drawing.Bitmap(500, 200);
            System.Drawing.Graphics objGraphics = System.Drawing.Graphics.FromImage(objBmp);
            objGraphics.Clear(System.Drawing.Color.AliceBlue);
            objGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            string[] strFont = new string[] { "Arial" };
            string[] strArray = new string[] { "a", "b", "c", "d", "e" };
            strRandom = "AAAAAA";//these are the characters for the captcha. In normal circumstances it would be random!

            /* Render the image */
            int _rotate = -1;
            objGraphics.RotateTransform(3);
            foreach (char _char in strRandom.ToCharArray())
            {
                /* Rotate the image */
                objGraphics.RotateTransform((float)(_rotate * 5));
                _rotate = (_rotate == 1) ? -1 : 1;

                /* Generate random y position */
                _yPosition = Convert.ToInt32(_randomNumberGenerator.Next(15, 20));

                /* Select random font */
                System.Drawing.Font objFont = new System.Drawing.Font("Arial", 22, System.Drawing.FontStyle.Bold);

                /* Output the next character */
                objGraphics.DrawString(_char.ToString(), objFont, System.Drawing.Brushes.Black, _xPosition, _yPosition);

                /* Get the width of the string added */
                System.Drawing.SizeF _stringSize = objGraphics.MeasureString(_char.ToString(), objFont);

                /* Dispose of the font */
                objFont.Dispose();

                /* Output the next character */
                objGraphics.DrawImage(objBmp, _xPosition, _yPosition);

                /* Increment x position */
                _xPosition = _xPosition + (_stringSize.Width * (float)0.8);

                /* Get bounding area */
                _xPositionMax = _xPosition;
                _yPositionMax = (int)(_yPosition + _stringSize.Height);
            }
            _xPositionMax += 20;
            _yPositionMax += 15;

            System.Drawing.Bitmap objBmpFinal = new System.Drawing.Bitmap((int)_xPositionMax, (int)_yPositionMax);
            System.Drawing.Graphics objGraphicsFinal = System.Drawing.Graphics.FromImage(objBmpFinal);
            System.Drawing.Rectangle _rectDest = new System.Drawing.Rectangle(0, 0, (int)_xPositionMax, (int)_yPositionMax);
            objGraphicsFinal.DrawImageUnscaledAndClipped(objBmp, _rectDest);

            /* Draw a curve over the image */
            float _yPositionMaxCurve = _yPositionMax - 20;
            System.Drawing.Pen _penCurve = new System.Drawing.Pen(System.Drawing.Color.Black, 2);
            objGraphicsFinal.DrawBezier(_penCurve,
                _randomNumberGenerator.Next(5, 10), _randomNumberGenerator.Next(5, (int)_yPositionMaxCurve),
                _randomNumberGenerator.Next((int)(_xPositionMax / 6), (int)(_xPositionMax / 5)), _randomNumberGenerator.Next((int)(_yPositionMaxCurve / 2), (int)_yPositionMaxCurve),              // y2
                _randomNumberGenerator.Next((int)(_xPositionMax / 4), (int)(_xPositionMax / 3)), _randomNumberGenerator.Next(5, (int)_yPositionMaxCurve),                             // y3
                _randomNumberGenerator.Next((int)(_xPositionMax - 5), (int)_xPositionMax), _randomNumberGenerator.Next(5, (int)_yPositionMaxCurve));                            // y4
            _penCurve.Dispose();

            /* Draw diagonal lines */
            System.Drawing.Pen _penHatch = new System.Drawing.Pen(System.Drawing.Color.Black, 1);
            for (int _i = -100; _i < _xPositionMax; _i += ((int)_xPositionMax / 8))
            {
                float _bottomPos = ((float)Math.Tan((Math.PI * 45 / 180.0)) * _yPositionMax);
                objGraphicsFinal.DrawLine(_penHatch, _i, 0, _bottomPos + _i, _yPositionMax);
            }
            for (int _i = 0; _i < (_xPositionMax + 100); _i += ((int)_xPositionMax / 8))
            {
                float _bottomPos = ((float)Math.Tan((Math.PI * 45 / 180.0)) * _yPositionMax);
                objGraphicsFinal.DrawLine(_penHatch, _i, 0, ((-_bottomPos) + _i), _yPositionMax);
            }
            _penHatch.Dispose();

            /* Draw bounding rectangle */
            System.Drawing.Pen _penBorder = new System.Drawing.Pen(System.Drawing.Color.Black, 1);
            objGraphicsFinal.DrawRectangle(_penBorder, 0, 0, (int)(_xPositionMax - 1), (int)(_yPositionMax - 1));
            _penBorder.Dispose();

            /* Draw random speckles */
            for (int _speckle = 0; _speckle < 100; _speckle++)
            {
                /* Generate a random colour */
                System.Drawing.Color _speckleColor = System.Drawing.Color.FromArgb((byte)_randomNumberGenerator.Next(0, 255), (byte)_randomNumberGenerator.Next(0, 255), (byte)_randomNumberGenerator.Next(0, 255));

                /* Create a brush */
                System.Drawing.SolidBrush _speckleBrush = new System.Drawing.SolidBrush(_speckleColor);

                /* Select random font */
                System.Drawing.Font _speckleFont = new System.Drawing.Font(strFont[_randomNumberGenerator.Next(0, (strFont.Length - 1))], _randomNumberGenerator.Next(2, 6), System.Drawing.FontStyle.Regular);

                /* Get speckle character */
                int i = Convert.ToInt32(_randomNumberGenerator.Next(0, (strArray.Length - 1)));
                string _speckleCharacter = strArray[i].ToString();

                /* Draw speckle */
                objGraphicsFinal.DrawString(_speckleCharacter, _speckleFont, _speckleBrush, _randomNumberGenerator.Next(0, (int)_xPositionMax), _randomNumberGenerator.Next(0, (int)_yPositionMax));

                /* Dispose of objects */
                _speckleBrush.Dispose();
                _speckleFont.Dispose();
            }

            /* Output the image */
            Response.ContentType = "image/GIF";
            objBmpFinal.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);

            objGraphics.Dispose();
            objGraphicsFinal.Dispose();

            objBmpFinal.Dispose();
            objBmp.Dispose();

            /* End the response */
            Response.End();
        }
    }
}

Win 2008R2 64 でどのように見えるかを示すいくつかの画像があります。

どのように見えるか: ワーキングキャプチャ画像

機能していません!!!! ここに画像の説明を入力

この PC を入手したばかりなので、一部の「役割」がオンになっていない可能性があります (ASP.NET、.NET3.5、静的コンテンツはすべてチェックされています)。

誰か明るいアイデアを思いつきましたか?

4

1 に答える 1

0

この問題を分割して克服する必要があります。これを行う方法は、出力に影響を与えていないもの (背景アイテム) を排除することから始めます。次に、ランダムな要素を削除するか (同じ結果が得られるようにジェネレーターをシードすることができます)、または定数を使用します。「この行があるとテキストが表示されませんが、それを取り出すとテキストが表示されます」ということになると、原因が特定されました。

キャプチャをいじるのは楽しいですが、デバッグと検証を非常に困難にする方法でそれを行っています. このタイプのコードは単体テストを行い、単体テストを可能にして、特定の開始シードを指定すると、どこでも一貫した出力が得られるようにする必要があります。

私たちの環境では、あるテスト サーバーにはあるバージョンのフォントがあり、別のサーバーにはないため、フォントがピクセル単位でレンダリングされないという問題が時々発生します。私はそれがあなたの問題だとは思いません。

于 2013-03-20T15:08:32.860 に答える