我有一段代码正在采用一个等式并将其转换为.png图像进行显示。 如果等式包含逗号(,) - 在转换为.png时,如果图像字节字符串已经被base64编码,则丢失。 如果没有,一切都很好,逗号显示。 一个例子 - 非base64 - 等式1,2显示为1,2的图像 Base64 - 等式1,2显示为12的图像
该等式来自查询字符串。例如 -
/.../.../GetEquationImage.aspx?eq=1%2C3&fontsize=13&fontfamily=RobotoDraft%2C%20Helvetica%20Neue%2C%20Helvetica%2C%20Arial%2C%20sans-serif&fontcolor=%23000000&base64=true
eq是我们正在使用的查询字符串值。在上述情况下,它是1%2C3' url使用javascript encodeURIComponent编码 当我从查询字符串中获取上述值时,它被评估为1,3,所以我不认为那里有任何问题。
我发现的一个解决方法是执行以下操作:
sEquation = sEquation.Replace(",", ",");
然而,这会导致许多连锁问题,这些问题很难修复,因此寻找另一种选择。
这是我目前正在运行的代码:
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
string sEquation = Request["eq"];
if (String.IsNullOrEmpty(sEquation))
return;
string sBase64 = Request["base64"];
bool bBase64Output = sBase64 == "true";
string sFontSize = Request["fontsize"];
string sFontFamily = Request["fontfamily"];
string sFontColor = Request["fontcolor"];
if (string.IsNullOrEmpty(sFontSize))
{
sFontSize = "12";
}
sFontSize = Regex.Match(sFontSize, @"\d*").Value;
float fFontSize;
if (String.IsNullOrEmpty(sFontSize) || !float.TryParse(sFontSize, out fFontSize))
fFontSize = 12f;
//adjust font size for personal zoom level
int iPerId = GetCurrentPersonId(null);
double dZoom = iPerId < 0 ? 1 : itPersonCache.GetEquationZoomLevel(Context, DatabaseAccess.GetDatabase(Context), iPerId, null);
fFontSize *= (float)dZoom;
Debug.Write("Generating equation image for \"" + sEquation + "\"...");
//create the equation object and obtain equation bitmap...
var oEquation = new Equation(sEquation.Replace("&code", "&#"), sFontFamily, fFontSize, sFontColor); //legacy replacement for old equations
MemoryStream oStream;
using (Bitmap oEquationBitmap = oEquation.Draw()) {
//...encode the bitmap as png image...
ImageCodecInfo oEncoder = GetEncoder(ImageFormat.Png);
var oParameters = new EncoderParameters();
var oQualityParam = new EncoderParameter(Encoder.Quality, 100L);
oParameters.Param[0] = oQualityParam;
oStream = new MemoryStream();
oEquationBitmap.Save(oStream, oEncoder, oParameters);
}
//...then send the image as the response
if (bBase64Output) {
byte[] ImageBytes = oStream.ToArray();
Response.ContentType = "text/plain";
Response.Write(Convert.ToBase64String(ImageBytes));
//piggyback baseline and height for equation alignment
Response.Write(string.Format("baseline={0}height={1}zoom={2}", (int)Math.Round(oEquation.BaselineOffset, 0, MidpointRounding.AwayFromZero), oEquation.ImageHeight, dZoom));
Debug.WriteLine(string.Format("sent via base64 text/plain ({0} bytes)", ImageBytes.Length));
}
else {
Response.ContentType = "image/png";
Response.BufferOutput = true;
oStream.WriteTo(Response.OutputStream);
Debug.WriteLine("sent via image/png");
}
}
有关另一种解决此问题的方法的建议吗?方程式显示为相当基本,因此丢失逗号是一个很大的禁忌。
base64编码也是一项要求。
我上面提到的修复 sEquation = sEquation.Replace(",", ",");
也是一个禁忌,因为它会产生影响。
任何帮助真的很感激。
/// <summary>
/// returns a bitmap with rendered formula
/// </summary>
/// <returns></returns>
override public Bitmap Draw()
{
if (oBaseSymbol == null || oBaseSymbol.fW <= 0 || oBaseSymbol.fH <= 0)
return oImage;
int iMargin = (int)Math.Round((BASE_MARGIN_LEFT + BASE_MARGIN_RIGHT) * oBaseSymbol.fFontSize);
int iWidth = (int)Math.Round(oBaseSymbol.fW) + iMargin;
oImage = new Bitmap(iWidth, (int)Math.Round(oBaseSymbol.fH));
oGraphics = Graphics.FromImage(oImage);
oGraphics.Clear(Color.Transparent);
// Set the text antialiasing and bitmap interoplation modes (so that bitmaps that are added
// to the equation bitmap are smoothed).
oGraphics.TextContrast = 0;
oGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
oGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
foreach (Symbol oSymbol in lsoSymbols) {
if (oSymbol.sType == "Symbol" || oSymbol.sType == "Expression") {
float fX = oSymbol.fGX + oSymbol.oSymbolData.fPaddingLeft * oSymbol.fFontSize;
float fY = oSymbol.fGY;
// For Cambria Math symbols fY must be reduced.
if (oSymbol.oSymbolData.bUseMathsFont)
fY -= MATHS_FONT_VERTICAL_SPACE_FACTOR / 2 * oSymbol.fFontSize;
oGraphics.DrawString(oSymbol.oSymbolData.sOut, oSymbol.oFont, oSymbol.oBrush, new PointF(fX, fY));
if (bDrawDebugLines) {
oGraphics.DrawRectangle(Pens.Blue, fX, fY, fX + oSymbol.fW, fY + oSymbol.fH);
oGraphics.DrawLine(Pens.Red, fX, fY + oSymbol.fBaselineOffset, fX + oSymbol.fW, fY + oSymbol.fBaselineOffset);
}
}
else if (oSymbol.sType == "MText") {
float fX = oSymbol.fGX;
float fY = oSymbol.fGY;
oGraphics.DrawString(oSymbol.sStr, oSymbol.oFont, oSymbol.oBrush, new PointF(fX, fY));
}
foreach (Rect oRect in oSymbol.lsoRectangles) {
if (!String.IsNullOrEmpty(oRect.sImageToUse)) {
if (oRect.sImageToUse == "Dot")
oGraphics.DrawString(".", oSymbol.oFont, oSymbol.oBrush, new PointF(oSymbol.fGX + oRect.fX, oSymbol.fGY + oRect.fY));
else if (oRect.sImageToUse == "DDot")
oGraphics.DrawString("..", oSymbol.oFont, oSymbol.oBrush, new PointF(oSymbol.fGX + oRect.fX, oSymbol.fGY + oRect.fY));
else if (oRect.sImageToUse == "Tilde")
oGraphics.DrawString("~", oSymbol.oFont, oSymbol.oBrush, new PointF(oSymbol.fGX + oRect.fX, oSymbol.fGY + oRect.fY));
else if (oRect.sImageToUse == "Hat")
oGraphics.DrawString(HttpUtility.HtmlDecode("^"), oSymbol.oFont, oSymbol.oBrush, new PointF(oSymbol.fGX + oRect.fX, oSymbol.fGY + oRect.fY));
else
lock (oDrawImageLock)
{
oGraphics.DrawImage(GetImage(oRect.sImageToUse), oSymbol.fGX + oRect.fX, oSymbol.fGY + oRect.fY, oRect.fW, oRect.fH);
}
}
else
oGraphics.FillRectangle(Brushes.Black, (int)Math.Round(oSymbol.fGX + oRect.fX), (int)Math.Round(oSymbol.fGY + oRect.fY), (int)Math.Round(oRect.fW), (int)Math.Round(oRect.fH));
}
}
if (bDrawDebugLines) {
oGraphics.DrawLine(Pens.Green, 0, oBaseSymbol.fBaselineOffset, oBaseSymbol.fGX + oBaseSymbol.fW, oBaseSymbol.fBaselineOffset);
oGraphics.DrawRectangle(Pens.Blue, 0, 0, oBaseSymbol.fW, oBaseSymbol.fH - 1);
}
return oImage;
}