简体   繁体   English

.NET System.Windows Server 2008R2 64bit与所有其他Windows相比的绘图差异(图像在2008R2-64中损坏,但在其他Windows上则没有)

[英].NET System.Drawing differences in Windows Server 2008R2 64bit compared to all other windows (image is broken in 2008R2-64 but not other Windows)

I have been given a development PC that has Windows Server 2008R2 64bit (x86) installed, so it is used as a workstation. 我得到了一台安装了Windows Server 2008R2 64位(x86)的开发PC,因此它被用作工作站。 My development environment is VS2008 targeting .NET3.5 (YES, 2008 !!!) 我的开发环境是针对.NET3.5的VS2008(是, 2008年 !!!)

In our website (which is a few years old now) there is a in-house developed Captcha. 在我们的网站(现在已有几年历史了)中,有一个内部开发的验证码。

To cut a long story short, the letters are not outputted on my dev machine 2008R2-64 but on all other windows (our test & live servers are 2003 64bit) and Virtual PC's (2008 32bit NOT R2, XP, Win7) they are. 长话短说,这些字母不会在我的开发机2008R2-64上输出,而是在所有其他窗口(我们的测试和实时服务器是2003 64位)和Virtual PC(2008 32位NOT R2,XP,Win7)上输出。

I have seen some posts on the web that saying that the way pixels is measured might have changed (hard to find out for certain) but not much else. 我在网上看到过一些帖子,说像素的测量方法可能已经改变(很难确定),但没有太多其他变化。

Here is a small web-application to illustrate the problem. 这是一个小的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();
        }
    }
}

and here are some images showing what it should look like and what it looks like on Win 2008R2 64. 这里有一些图片显示它应该是什么样子,什么它看起来像在Win 2008R2 64。

How it should look: 外观如何: 工作验证码图片

Not Working!!!! 无法正常工作!!! 在此处输入图片说明

I have only just got this PC so it's possible that some of the "roles" are not switched on (ASP.NET, .NET3.5, Static Content are all ticked). 我只有一台PC,所以可能没有打开某些“角色”(ASP.NET,.NET3.5,静态内容均已打勾)。

Anyone got any bright ideas? 有人有什么好主意吗?

You need to divide and conquer this problem. 您需要分而治之。 The way to do this is to start eliminating the things that aren't affecting your output (background items). 这样做的方法是开始消除不影响输出的内容(背景项)。 Then eliminate the random elements (you could seed your generator so that it gives you the same results), or use constants. 然后消除随机元素(您可以为生成器添加种子,以便它提供相同的结果),或使用常量。 When you can get it down to "when I have this line in I get no text, but when I take it out, I have text" you have located the cause. 当您可以将其归结为“当我输入此行时,我没有收到任何文本,但是当我将其取出时,我却收到了文本”时,您就可以找到原因。

It's fun to mung around with the captcha, but you've done it in a way that makes it very hard to debug and verify. 与验证码混在一起很有趣,但是您这样做的方式使得调试和验证非常困难。 This type of code should be unit tested and made unit testable so that given a particular starting seed you get consistent output everywhere. 这种类型的代码应进行单元测试,并使其可以进行单元测试,以便在给定特定的起始种子的情况下,您到处都能获得一致的输出。

In our environment, we have issues now and again where fonts don't render pixel-identical because one test server has one version of the font and another doesn't. 在我们的环境中,我们经常遇到字体无法呈现像素相同的问题,因为一个测试服务器使用一种版本的字体,而另一种则没有。 I don't see that as your issue. 我不认为这是您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Windows Server 2008 R2 64位中内置的C#.NET应用程序无法在Windows 7 32位中运行 - C# .NET application built in Windows Server 2008 R2 64bit doesn't run in Windows 7 32bit 将应用程序移动到服务器2008R2 64位时出现AccessViolationException - AccessViolationException when moving app to server 2008R2 64bit Windows Server 2008R2 IIS Appcrash - System.StackOverflowException - Windows Server 2008R2 IIS Appcrash - System.StackOverflowException 如何从32位.NET App在64位Windows Server 2008上启动ServerManager.msc? - How can I start ServerManager.msc on a 64bit Windows Server 2008 from a 32bit .NET App? Windows Server 2008 R2 Standard 64位的PrintDocument问题 - PrintDocument issues with Windows Server 2008 R2 Standard 64-bit 无法确定UAC在Windows Server 2008 64位中是否处于活动状态 - Cannot determine whether UAC is active in Windows Server 2008 64 bit Microsoft Office Interop Excel在Windows 2008 64bit和Office 2007 32bit上无法关闭 - Microsoft Office Interop Excel is not closing on windows 2008 64bit and office 2007 32bit 无法在Windows 2008 R2 64位中为C#应用程序生成临时类 - Unable to generate temporary class in Windows 2008 R2 64 bit for C# app Windows Server 2012R2 64位上的NAudio MediaFoundationReader ReadFail - NAudio MediaFoundationReader ReadFail On Windows Server 2012R2 64bit Windows 7 64bit上的emgucv - emgucv on windows 7 64bit
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM