ThinkGeo.com    |     Documentation    |     Premium Support

Contrast control for RasterLayers

How could one control the contrast for a RasterLayer?



Ryan, 
  
 Thanks for your questions! 
  
 The RasterLayer  can be controlled by RGB translation, transparency, grayscale and negative. I’m not sure the meaning for the contrast, we don’t have a API to set the contrast directly, but I think you can set the properties above to control the contrast for a RasterLayer. 
  
 Hope it can help you, 
  
 Thanks, 
  
 Scott,

Scott, 
 Thanks for your response. 
  
 If there is a way to adjust the contrast with the above API, I don’t understand how.  Grayscale and negative are simply boolean values that make the image a grayscale or negative of itself, and transparency adjusts the transparency of the image.  RGB translation will simply add a bias to the respective channel of the image.  This would adjust the brightness, but not the contrast.  Brightness and contrast are related but are not the same thing.  Together they form a linear translation function that is applied to each pixel in the image, the brightness being the bias or intercept point, and contrast being the slope.  ImageJ has a nice interface for adjusting the brightness/contrast of an image if you would like to see this in action. 
  
 I understand if your API does not implement this out-of-the-box, I am interested in writing some code to do the processing.  Here is what I currently have: 
 1) Subclass WmsRasterSource, and call it AdjustableWmsRasterSource 
 2) Subclass WmsLayerSource, and call it AdjustableWmsLayerSource 
 3) Set the ImageSource of AdjustableWmsLayerSource to be an AdjustableWmsRasterSource. 
 4) Override the GetImageCore method in the AdjustableWmsRasterSource to be this: 
  
        protected override GeoImage GetImageCore(RectangleShape worldExtent, int canvasWidth, int canvasHeight)
        {
            using (GeoImage originalGeoImage = base.GetImageCore(worldExtent, canvasWidth, canvasHeight))
            {
                using (Stream geoImgStream = originalGeoImage.GetImageStream(new GdiPlusGeoCanvas()))
                {
                    Bitmap orgGeoBitmap = (Bitmap)Bitmap.FromStream(geoImgStream);
                    Bitmap contrastedGeoBitmap = AdjustContrast(orgGeoBitmap, this.Contrast);   // Method that adjusts the contrast of a bitmap

                    MemoryStream contrastedImgStream = new MemoryStream();
                    contrastedGeoBitmap.Save(contrastedImgStream, System.Drawing.Imaging.ImageFormat.Tiff);

                    GeoImage geoimg = new GeoImage(contrastedImgStream);
                    return geoimg;
                }
            }
        }
 
  
 There are a couple of issues with the above solution: 
 1) Since the adjustment is in the GetImageCore method, the contrast can’t be adjusted without re-downloading the image.  I would like to be able to adjust the contrast in some sort of post-processing method. 
 2) Cached imagery is no good if the contrast is adjusted. 
 3) The layer needs to be fully refreshed when adjusting the contrast. 
  
 Thanks, 
 Ryan

Ryan, 
  
 Sorry for answering you delay, I think you have implemented your requirements fully just there are several issues, actually, I’m not so familiar with contrast for images, we don’t have the APIs to implement it directly, if you have finished it can you send your sample to us and we can have an investigation based on your sample for these issues what you mentioned. 
  
 Thanks, 
  
 Scott,

I've attached a demo project showing how I am currently adjusting the brightness and contrast on a rasterlayer.  My current method involves calling map.Refresh() which results in a call to a wms server.  This is quite expensive as the image needs to be re-downloaded.  I would like to change the contrast of the image without needing to re-download it.


 


Thanks,


Ryan



DemoThinkGeoContrast.zip (39.6 KB)

 Ryan,


Thanks for the sample!  This made it really easy to see what you wanted.


I have modified your sample where it won't refretch the image from the WMS Server when the brightness or contrast is modified.  Basically what I did was keep a copy of the previous bitmap and previous world extent in memory and if the worldextent doesn't change when the GetImageCore is called use the prevous bitmap and don't refetch the bitmap. 


You may want to clean up the code a little bit but I think you wil get the idea.


Attached is your sample updated with my code, take a look and let us know if you have any questions.


Thanks!



001_DemoThinkGeoContrast.zip (42.2 KB)