2012-09-05 74 views
0

我是MonoTouch的新手,最近我將代碼從標準C#轉換爲符合MonoTouch的代碼,因此可以在iPhone應用程序中使用它。我已經成功地轉換代碼,但是我碰到的這種方法的一個問題,我用它來返回一個位圖背景:MonoTouch中的CGBitmapContext拋出無效的句柄異常

private CGBitmapContext ExtractWriteableBitmap(RGBPaletteRecord rgbPalette, double dpi, ChartIndexFile indexFile, RasterChartFile chartFile) 
     { 
      CGBitmapContext bitmapImage = null; 
      TileRecord tile; 

      // calc the number of tiles in each plane 
      int tileCountX = indexFile.TileIndexRecords.Max(ti => ti.X); 
      int tileCountY = indexFile.TileIndexRecords.Max(ti => ti.Y); 

      // create the big picture 
      int pixelWidth = (tileCountX + 1) * TileRecord.PixelWidth; 
      int pixelHeight = (tileCountY + 1) * TileRecord.PixelHight; 

      int intDPI = Convert.ToInt32(dpi); 

      int bytesPerRow = (int)TileRecord.PixelWidth * 4; // note that bytes per row should 
    //be based on width, not height. 

      CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB(); 
      CGImageAlphaInfo info = CGImageAlphaInfo.NoneSkipFirst; 

      // create the big picture 
      bitmapImage = new CGBitmapContext(System.IntPtr.Zero, pixelWidth, pixelHeight, intDPI, intDPI, colorSpace, info); 

      byte[] sourceArray; 
      RectangleF sourceRect; 

      //copy the tiles into the big picture 
      int index = 0; 
      foreach (TileIndexRecord tileIndexRecord in indexFile.TileIndexRecords) 
      { 
       // get the tile record 
       tile = chartFile.TileRecords[index]; 

       // extract the byte array for the given palette 
       sourceArray = tile.GetBytes(rgbPalette); 

       GCHandle pinnedArray = GCHandle.Alloc(sourceArray, GCHandleType.Pinned); 
       IntPtr pointer = pinnedArray.AddrOfPinnedObject(); 
       //do your stuff 
       //pinnedArray.Free(); 

       CGImage image = new CGImage(pointer); 
       sourceRect = new RectangleF(0, 0, TileRecord.PixelWidth, TileRecord.PixelHight); 

       bitmapImage.DrawImage(new RectangleF(0,0,128,128),image); 

       // copy the tile image into the big picture 
       //bitmapImage.WritePixels(sourceRect, sourceArray, TileRecord.Stride, (tileIndexRecord.X * TileRecord.PixelWidth), (tileIndexRecord.Y * TileRecord.PixelHight)); 

       // increment the index 
       index++; 
      } 
      return bitmapImage; 
     } 

這裏是堆棧跟蹤:

System.Exception: Invalid handle 
    at MonoTouch.CoreGraphics.CGContext..ctor (IntPtr handle, Boolean owns) [0x00022] in /Developer/MonoTouch/Source/monotouch/src/shared/CoreGraphics/CGContext.cs:136 
    at MonoTouch.CoreGraphics.CGBitmapContext..ctor (IntPtr data, Int32 width, Int32 height, Int32 bitsPerComponent, Int32 bytesPerRow, MonoTouch.CoreGraphics.CGColorSpace colorSpace, CGImageAlphaInfo bitmapInfo) [0x00000] in <filename unknown>:0 
    at Jargoon.Data.Arcs.Loader.ExtractWriteableBitmap (Jargoon.Data.Arcs.Records.RGBPaletteRecord rgbPalette, Double dpi, Jargoon.Data.Arcs.Raschts.ChartIndexFile indexFile, Jargoon.Data.Arcs.Raschts.RasterChartFile chartFile) [0x00079] in /Users/jacknutkins/Desktop/Jargoon/ARCSViewer/ARCSViewer/Loader.cs:569 
    at Jargoon.Data.Arcs.Loader.GetHiResImage (Jargoon.Data.Arcs.Records.RGBPaletteRecord rgbPalette) [0x00000] in /Users/jacknutkins/Desktop/Jargoon/ARCSViewer/ARCSViewer/Loader.cs:361 
    at ARCSViewer.ARCSViewerViewController.ViewDidLoad() [0x0001c] in /Users/jacknutkins/Desktop/Jargoon/ARCSViewer/ARCSViewer/ARCSViewerViewController.cs:37 
    at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) 
    at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00042] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:29 
    at ARCSViewer.Application.Main (System.String[] args) [0x00000] in /Users/jacknutkins/Desktop/Jargoon/ARCSViewer/ARCSViewer/Main.cs:17 

的錯誤發生在該行:

// create the big picture 
      bitmapImage = new CGBitmapContext(System.IntPtr.Zero, pixelWidth, pixelHeight, intDPI, intDPI, colorSpace, info); 

我很新的MonoTouch的,所以如果它已經昭然若揭了嘗試,並承擔與我,但任何人都可以解釋怎麼回事?

回答

1

這通常發生在內存不足時。 (設備)控制檯通常會打印更多信息。

我的猜測是你沒有釋放你創建的CGBitmapContext。

+0

爲輸入而歡呼,我編輯了問題與我得到的其他堆棧跟蹤,我將如何去釋放上下文?歡呼聲 –

+1

第一次調用這段代碼或經過多次迭代後是否發生異常?你傳遞給CGBitmapContext構造函數的參數是什麼(如果你嘗試創建一個比例太大的位圖,它會失敗) –

+0

這就是問題(方式太大),昨晚我設法弄清楚了,非常感謝。 –

相關問題