DrawText randomly gives error: Parameter is not valid
DrawText randomly gives error: Parameter is not valid
我有一个错误:
Parameter is not valid.
此错误大约每 5 次发生 1 次。
错误发生在这一行:
TextRenderer.DrawText(drawing, "Code12", font, fullWidthRectangle,
textColor,
flags);
小代码示例(非实际代码):
public Image CreateTripDetailPreview(Image image)
{
using (var fontCollection = new PrivateFontCollection())
using (var fontCollectionBold = new PrivateFontCollection())
{
fontCollection.AddFontFile("Assets\SourceSansPro-Regular.ttf");
fontCollectionBold.AddFontFile("Assets\SourceSansPro-Bold.ttf");
//This will be used to define heigt of text and allign text
Rectangle fullWidthRectangle;
var widthInDip = 360;
var imgHeigtInDip = 168;
var canvasWidth = 1080;
var canvasHeight = 1200;
var dip = canvasWidth / widthInDip;
var leftRightMargin = 15 * dip;
var resolutionScale = 5;
using (Image img = new Bitmap(canvasWidth * resolutionScale, canvasHeight * resolutionScale))
using (Graphics drawing = Graphics.FromImage(img))
{
//Clear 'background' and make it white
drawing.Clear(Color.White);
var imageHeight = (int)167.5 * dip;
var height = imageHeight * resolutionScale;
using (var cityImageBitmap = new Bitmap(image))
using (var resizedCityImage = new Bitmap(cityImageBitmap, new Size(canvasWidth, imageHeight)))
{
canvasWidth *= resolutionScale;
canvasHeight *= resolutionScale;
dip *= resolutionScale;
leftRightMargin *= resolutionScale;
TextFormatFlags flags;
using (var regularFont = new Font(fontCollection.Families[0], 1, FontStyle.Regular))
using (var boldFont = new Font(fontCollectionBold.Families[0], 1, FontStyle.Regular)
) //1 as default fontsize, fontsize will be calculated for each property
{
Color textColor = Color.FromArgb(102, 102, 102);
//FlightCode
height += 4 * dip;
fullWidthRectangle = new Rectangle(leftRightMargin, height,
canvasWidth - leftRightMargin * 2,
(int)22.5 * dip);
using (Font font = GetFontSizeByBox(drawing, "Code12",
fullWidthRectangle.Size,
regularFont))
{
flags = TextFormatFlags.NoPadding | TextFormatFlags.HorizontalCenter;
TextRenderer.DrawText(drawing, "Code12", font, fullWidthRectangle,
textColor,
flags);
}
using (var result = new Bitmap(img, canvasWidth / resolutionScale, canvasHeight / resolutionScale))
using (Graphics drawing2 = Graphics.FromImage(result))
{
drawing2.DrawImage(resizedCityImage, new Point(0, 0));
return new Bitmap(result);
}
}
}
}
}
}
GetFontSizeByBox 方法:
private static Font GetFontSizeByBox(Graphics g, string longString, Size room, Font preferedFont, int extraSize = 0)
{
SizeF realSize = g.MeasureString(longString, preferedFont);
var heightScaleRatio = room.Height / realSize.Height;
var widthScaleRatio = room.Width / realSize.Width;
var scaleRatio = heightScaleRatio < widthScaleRatio ? heightScaleRatio : widthScaleRatio;
var scaleFontSize = preferedFont.Size * scaleRatio;
return new Font(preferedFont.FontFamily, scaleFontSize + extraSize, preferedFont.Style);
}
注释
此方法顶部的 GC.Collect()
解决了问题,我不想使用此 'fix' 更好地防止它。
- 所有一次性的都在 using 语句中
- 该方法大部分时间有效,1/5 次失败
错误时DrawText的值:
- 图形对象(属性可访问)
- "Code12" 常规字符串
- 字体
Name = "Source Sans Pro" Size=179.088287
(属性可访问)
- 矩形
X = 225 Y = 2565 Width = 4950 Height = 330
- 颜色
Name=ff666666, ARGB=(255, 102, 102, 102)
- 旗帜
TextFormatFlags.HorizontalCenter | TextFormatFlags.NoPadding
如果有人知道我为什么会收到此错误或如何修复它,我们将不胜感激。
好的,我找到了解决方案,正如 Hans Passant 在方法顶部所说 GC.Collect();
将解决问题。这确实有效,但我想找出原因。
代码的结构方式在方法完成后将处理所有一次性对象(因为所有 using 语句),32bit
应用程序中有足够的内存 运行这种方法一次或两次。但是一旦在某些代的垃圾仍然存在的情况下调用该方法,它就会在制作位图时崩溃。
解法:
如果你有这个问题并且你不想每次你 运行 你的方法时都强制垃圾收集,你可以像这样设置一个阈值:
if( Process.GetCurrentProcess().PrivateMemorySize64 > someNumber )
{
GC.Collect();
}
事实证明这对我不起作用,因为每次都达到阈值,所以我每次都选择 GC.Collect();
。如果有人有更好的解决方案(不增加内存),请不要犹豫post。
我有一个错误:
Parameter is not valid.
此错误大约每 5 次发生 1 次。
错误发生在这一行:
TextRenderer.DrawText(drawing, "Code12", font, fullWidthRectangle,
textColor,
flags);
小代码示例(非实际代码):
public Image CreateTripDetailPreview(Image image)
{
using (var fontCollection = new PrivateFontCollection())
using (var fontCollectionBold = new PrivateFontCollection())
{
fontCollection.AddFontFile("Assets\SourceSansPro-Regular.ttf");
fontCollectionBold.AddFontFile("Assets\SourceSansPro-Bold.ttf");
//This will be used to define heigt of text and allign text
Rectangle fullWidthRectangle;
var widthInDip = 360;
var imgHeigtInDip = 168;
var canvasWidth = 1080;
var canvasHeight = 1200;
var dip = canvasWidth / widthInDip;
var leftRightMargin = 15 * dip;
var resolutionScale = 5;
using (Image img = new Bitmap(canvasWidth * resolutionScale, canvasHeight * resolutionScale))
using (Graphics drawing = Graphics.FromImage(img))
{
//Clear 'background' and make it white
drawing.Clear(Color.White);
var imageHeight = (int)167.5 * dip;
var height = imageHeight * resolutionScale;
using (var cityImageBitmap = new Bitmap(image))
using (var resizedCityImage = new Bitmap(cityImageBitmap, new Size(canvasWidth, imageHeight)))
{
canvasWidth *= resolutionScale;
canvasHeight *= resolutionScale;
dip *= resolutionScale;
leftRightMargin *= resolutionScale;
TextFormatFlags flags;
using (var regularFont = new Font(fontCollection.Families[0], 1, FontStyle.Regular))
using (var boldFont = new Font(fontCollectionBold.Families[0], 1, FontStyle.Regular)
) //1 as default fontsize, fontsize will be calculated for each property
{
Color textColor = Color.FromArgb(102, 102, 102);
//FlightCode
height += 4 * dip;
fullWidthRectangle = new Rectangle(leftRightMargin, height,
canvasWidth - leftRightMargin * 2,
(int)22.5 * dip);
using (Font font = GetFontSizeByBox(drawing, "Code12",
fullWidthRectangle.Size,
regularFont))
{
flags = TextFormatFlags.NoPadding | TextFormatFlags.HorizontalCenter;
TextRenderer.DrawText(drawing, "Code12", font, fullWidthRectangle,
textColor,
flags);
}
using (var result = new Bitmap(img, canvasWidth / resolutionScale, canvasHeight / resolutionScale))
using (Graphics drawing2 = Graphics.FromImage(result))
{
drawing2.DrawImage(resizedCityImage, new Point(0, 0));
return new Bitmap(result);
}
}
}
}
}
}
GetFontSizeByBox 方法:
private static Font GetFontSizeByBox(Graphics g, string longString, Size room, Font preferedFont, int extraSize = 0)
{
SizeF realSize = g.MeasureString(longString, preferedFont);
var heightScaleRatio = room.Height / realSize.Height;
var widthScaleRatio = room.Width / realSize.Width;
var scaleRatio = heightScaleRatio < widthScaleRatio ? heightScaleRatio : widthScaleRatio;
var scaleFontSize = preferedFont.Size * scaleRatio;
return new Font(preferedFont.FontFamily, scaleFontSize + extraSize, preferedFont.Style);
}
注释
-
此方法顶部的
GC.Collect()
解决了问题,我不想使用此 'fix' 更好地防止它。- 所有一次性的都在 using 语句中
- 该方法大部分时间有效,1/5 次失败
错误时DrawText的值:
- 图形对象(属性可访问)
- "Code12" 常规字符串
- 字体
Name = "Source Sans Pro" Size=179.088287
(属性可访问) - 矩形
X = 225 Y = 2565 Width = 4950 Height = 330
- 颜色
Name=ff666666, ARGB=(255, 102, 102, 102)
- 旗帜
TextFormatFlags.HorizontalCenter | TextFormatFlags.NoPadding
如果有人知道我为什么会收到此错误或如何修复它,我们将不胜感激。
好的,我找到了解决方案,正如 Hans Passant 在方法顶部所说 GC.Collect();
将解决问题。这确实有效,但我想找出原因。
代码的结构方式在方法完成后将处理所有一次性对象(因为所有 using 语句),32bit
应用程序中有足够的内存 运行这种方法一次或两次。但是一旦在某些代的垃圾仍然存在的情况下调用该方法,它就会在制作位图时崩溃。
解法:
如果你有这个问题并且你不想每次你 运行 你的方法时都强制垃圾收集,你可以像这样设置一个阈值:
if( Process.GetCurrentProcess().PrivateMemorySize64 > someNumber )
{
GC.Collect();
}
事实证明这对我不起作用,因为每次都达到阈值,所以我每次都选择 GC.Collect();
。如果有人有更好的解决方案(不增加内存),请不要犹豫post。