0

我得到了一台安装了 Windows Server 2008R2 64bit (x86) 的开发 PC,因此它被用作工作站。我的开发环境是针对 .NET3.5 的 VS2008(是的,2008!!!)

在我们的网站(现在已经有几年了)有一个内部开发的验证码。

长话短说,这些字母不会在我的开发机器 2008R2-64 上输出,而是在所有其他窗口(我们的测试和实时服务器是 2003 64 位)和 Virtual PC(2008 32 位而不是 R2、XP、Win7)上输出。

我在网上看到一些帖子说像素的测量方式可能已经改变(很难确定),但没有太大变化。

这是一个小的网络应用程序来说明这个问题。

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 上的样子。

它应该看起来如何: 工作验证码图像

不工作!!!! 在此处输入图像描述

我刚拿到这台电脑,所以可能有些“角色”没有打开(ASP.NET、.NET3.5、静态内容都打勾)。

有人有什么好主意吗?

4

1 回答 1

0

你需要分而治之。做到这一点的方法是开始消除不影响输出的事物(背景项目)。然后消除随机元素(您可以为您的生成器播种,以便它为您提供相同的结果),或使用常量。当您可以将其归结为“当我输入此行时,我没有文字,但是当我将其取出时,我有文字”,您就找到了原因。

玩转验证码很有趣,但是您这样做的方式使得调试和验证变得非常困难。这种类型的代码应该进行单元测试并使单元可测试,以便给定特定的起始种子,您可以在任何地方获得一致的输出。

在我们的环境中,我们时不时会遇到字体不呈现像素相同的问题,因为一个测试服务器有一个版本的字体而另一个没有。我不认为这是你的问题。

于 2013-03-20T15:08:32.860 回答