ThinkGeo.com    |     Documentation    |     Premium Support

Transparent GeoImages

 We are trying to use transparent icons as GeoImages in ValueStyles. Bascially, we have a set of icons that, based on a ValueStyle, we want to display. When constructing the ValueStyle, we want to set a transparent color on the image, like this thread: gis.thinkgeo.com/Support/Dis...fault.aspx


The sample code in that thread doesn't dispose of the stream, and if the stream is disposed, the icons do not show up. When using a large number of GeoImages, memory consumption grows until the application crashes with an OutOfMemory exception.


Any suggestions on how to construct a GeoImage from a MemoryStream and then dispose of the stream?



Paul, 
  
 Thanks for your question! 
  
 Actually, if you dispose the geoimage’s stream obviously it would dispose the associate images also. For this issue I really don’t have any good solution for you, the stream is associated to the GeoImage object, if you dispose the stream, obviously the image would be dispose also. So if you have a large number fo GeoImages need to display, I suggest to draw a part of the geoimages first them dispose them and draw the other GeoImages then. 
  
 Thanks, 
  
 Scott,

I did some additional testing this morning. It doesn’t look like it is related to the number of streams after all. 
  
 If I add 1000 Features to the InMemoryFeatureLayer, all with the same value in the FeatureColumn that points to my ValueStyle with my one GeoImage, I can watch memory consumption of the application grow to nearly 1GB. The image file pointed to be the stream used by the GeoImage is only 1K. 
  
 I don’t see anywhere else along this code path that I could be consuming large amounts of memory. When the OutOfMemory exception occurs, this is the stack: 
  
  
 System.OutOfMemoryException: Out of memory. 
    at System.Drawing.Graphics.CheckErrorStatus(Int32 status) 
    at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y) 
    at System.Drawing.Graphics.DrawImageUnscaled(Image image, Int32 x, Int32 y) 
    at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.NRY=(Graphics NhY=, RectangleShape NxY=) 
    at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.3xU=(Boolean 4BU=, RectangleShape 4RU=) 
    at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.3RU=(RectangleShape 3hU=) 
  
 Any thoughts?

 Hi Paul,



 


I created a sample that wants to reproduce your problem but with no luck, the memory usage is not increased, could you look at it?


            Bitmap bitmap = new Bitmap(@"..\..\SampleData\Data\United States.png");
            bitmap.MakeTransparent(Color.Black);
            MemoryStream stream = new MemoryStream();
            bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            GeoImage geoimage = new GeoImage(stream);

            InMemoryFeatureLayer bitmapLayer = new InMemoryFeatureLayer();
            bitmapLayer.Open();
            bitmapLayer.Columns.Add(new FeatureSourceColumn("key"));
            bitmapLayer.Close();
            PointStyle pointStyle = new PointStyle(geoimage);
            ValueStyle valueStyle = new ValueStyle();
            valueStyle.ColumnName = "key";
            valueStyle.ValueItems.Add(new ValueItem("value", pointStyle));
            bitmapLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);
            bitmapLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            byte[] wkb = new PointShape(-95.2806, 38.9554).GetWellKnownBinary();
            for (int i = 0; i < 1000; i++)
            {
                Feature feature = new Feature(wkb, Guid.NewGuid().ToString(), new string[] { "key:value" });
                bitmapLayer.InternalFeatures.Add(Guid.NewGuid().ToString(), feature);
            }
            LayerOverlay overlay = new LayerOverlay();
            overlay.Layers.Add(bitmapLayer);
            winformsMap1.Overlays.Add(overlay);

            winformsMap1.CurrentExtent = new RectangleShape(-165.946875, 86.4359375, -35.86875, -6.3765625);
            winformsMap1.Refresh();

Thanks,


 


James