[英].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.