2017-05-05 56 views
0

我有一個錯誤:DrawText的隨機給出錯誤:參數是無效

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); 
    } 

注意

  1. GC.Collect()在這個方法的頂部解決了這個問題,我不希望使用此「修復」爲更好地防止它。
  2. 一切都一次性在使用語句
  3. 的方法工作的大部分時間,1/5次失敗

價值觀的DrawText的時出現錯誤:

  • Graphics對象(屬性可訪問)
  • 「Code12」常規字符串
  • 字體Name = "Source Sans Pro" Size=179.088287(pr operties訪問)
  • 矩形X = 225 Y = 2565 Width = 4950 Height = 330
  • 顏色Name=ff666666, ARGB=(255, 102, 102, 102)
  • 標誌TextFormatFlags.HorizontalCenter | TextFormatFlags.NoPadding

如果有誰知道爲什麼我得到這個錯誤,或者如何解決它,任何幫助表示讚賞。

+0

調用'TextRenderer.DrawText'時檢查參數的值?你有什麼價值? –

+0

@MightyBadaboom在示例中它們總是相同的(並且它失敗了大約1/5次),所以它不可能是它的值。我會去檢查你,雖然 – EpicKip

+0

@MightyBadaboom添加了值 – EpicKip

回答

0

好的,我找到了解決方案,正如漢斯帕斯坦所說的GC.Collect();在方法的頂部將解決問題。這確實有效,但我想找出原因。

結構化代碼的方式所有的一次性對象將在方法完成後處理(因爲所有的使用語句),在一個32bit應用程序中有足夠的內存來運行此方法一次或兩次。但只要該方法被調用並存在一些代垃圾,它就會在製作位圖時崩潰。

解決方案:
如果你有這樣的問題,你不wan't每次運行你的方法時,迫使垃圾收集你可以設置一個門檻,像這樣:

if(Process.GetCurrentProcess().PrivateMemorySize64 > someNumber) 
{ 
    GC.Collect(); 
} 

原來這對我來說並不適用,因爲每次都會觸發門檻,所以我只是每次都用GC.Collect();來解決。如果有人有更好的解決方案(不增加記憶)不要猶豫發佈。

+0

似乎很奇怪,內存不足並不會導致GC無論如何發射。我認爲這是它的工作原理。 – dannyhut

+0

@dannyhut這也是我的想法(和老年人在這裏)它的工作。但不知何故,這不會計算GDI創建位圖?我不確定,張貼我的發現,因爲它可能有助於某人;) – EpicKip