ThinkGeo.com    |     Documentation    |     Premium Support

GDIPlusRasterLayer Background now dark

Hi,



While moving to version 8 libraries, I’ve noticed that when I import raster files that the background of the image now appears to be almost black in appearance.  The same code running with my version 7 libraries shows transparent as I expect.



See attached images running from the same code with only the libraries changed.



Regards,

Damian



Hi Damian,



Seems that we are unable to reproduce the problem with our own data, would you please share some codes and your test file here? If it’s bigger than the upload size, please send it to forumsupport@thinkgeo.com or ask sales@thinkgeo.com for a FTP address?



Thanks,

Johnny

Hi Damian,



We are still unable to reproduce the problem you mentioned, with DesktopEdition 8.0.0.0. Here as following is the result we got:





I was wondering if you give the value to “KeyColors”, thus the transparent is replaced with other colors. Could you create a demo for us?



Thanks,

Johnny

Hi Johnny,



See attached project.  This is built with version 7 map control and 7.0.0.162 libraries.



You will need to use the test image and copy it to the reference location.



If you run this, you will see the shallow ocean background appear behind the image and transparent areas show shallow ocean appropriately.



If you then remove the map control and replace with version 8 and 8.0.0.300 libraries or higher, you will see the image now has a near black background.



I am pretty sure that version 8 is just requiring some parameter to be set that version 7 did not, so would appreciate to know what it is I need to set.



On another related issue, I am having a problem that the GDIPlusRasterLayer does not have the ability to set the WorldFilePathName just like you can set the PathFileName.  So, when I serialize a file and then subsequently reopen it, I can’t make any update to the WorldFilePathName if the user has done any file manipulations.  This is similar to the ShapeFileFeatureLayer where you have a ShapePathFileName and IndexPathFileName which are both allowed to be set.  I think GDIPlusRasterLayer should allow this as well.



Regards,

Damian

RasterLayerProblem.zip (47 KB)

Hi Damian,



Thanks for your demo, we did remove the code for dealing with black areas to transparent in Map Suite 8.0, now you can try the code as following to get what you want:




public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
 
    private void Form1_Load(object sender, EventArgs e)
    {
        winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
        winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);
        string imageFile = @"…\TestImage\TestForThinkGeo.tif";
        string worldFile = @"…\TestImage\TestForThinkGeo.tfw";
        string prjFileName = @"…\TestImage\TestForThinkGeo.prj";
        string prjFileText = System.IO.File.ReadAllText(prjFileName);
 
        GdiPlusRasterLayer imageLayer = new GdiPlusRasterLayer(imageFile, worldFile);
        MyManagedProj4Projection proj4 = new MyManagedProj4Projection();
 
        proj4.InternalProjectionParametersString = Proj4Projection.ConvertPrjToProj4(prjFileText);
        // set the external projection.
        proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetWgs84ParametersString();
        imageLayer.ImageSource.Projection = proj4;
        proj4.Open();
 
        imageLayer.Open();
 
        LayerOverlay cultureOverlay = new LayerOverlay();
        cultureOverlay.Name = "CultureOverlay";
        cultureOverlay.Layers.Add("TestImage", imageLayer);
        winformsMap1.Overlays.Add("CultureOverlay", cultureOverlay);
        RectangleShape extents = imageLayer.GetBoundingBox();
        winformsMap1.CurrentExtent = imageLayer.GetBoundingBox();
        winformsMap1.Refresh();
    }
 
    private void button1_Click(object sender, EventArgs e)
    {
 
    }
}
 
public class MyManagedProj4Projection : ManagedProj4Projection
{
    protected override RasterProjectionResult ConvertToExternalProjectionCore(GeoImage image, RectangleShape imageExtent)
    {
        RasterProjectionResult result = base.ConvertToExternalProjectionCore(image, imageExtent);
        GdiPlusGeoCanvas canvas = new GdiPlusGeoCanvas();
        Stream stream = result.Image.GetImageStream(canvas);
        Bitmap map = new Bitmap(stream);
        for (int i = 0; i < map.Height; i++)
        {
            for (int j = 0; j < map.Width; j++)
            {
                Color color = map.GetPixel(j, i);
                if (color.R == 0 && color.G == 0 && color.B == 0) color = Color.Transparent;
                map.SetPixel(j, i, color);
            }
        }
        MemoryStream memStream = new MemoryStream();
        map.Save(memStream, ImageFormat.Tiff);
        result.Image = new GeoImage(memStream);
        return result;
    }
}



Thanks,

Johnny

Hi Johnny, 
  
 Unfortunately, that’s not quite right.  If you zoom into the area in the North along the slope, you will find that the areas which have hill shading now have some transparent pixels which were erased because you substituted black for transparent. 
  
 There must be some other identifier in the pixel that suggests something is transparent (i.e. Alpha value, or IsEmpty, etc.). 
  
 And, my code is going to be a bit worse for wear having to use a custom override. 
  
 What of my question on the Raster world file path? 
  
 Regards, 
 Damian

Hi Damian, 
  
 The reason is that we replaced all the blank pixel to transparent in the code "MyManagedProj4Projection" we provided before. The reason is that the projection of raster comes from the GDAL engine, where it deal with all the images with RGB, in other words, the Alpha channel is missed, we are unable to know which area should be replaced with transparent. The only workaround is that you can do some extent check in the code we provided to make sure it just replaces the blank pixel to transparent in your expected area. 
  
 Thanks, 
 Johnny