ThinkGeo.com    |     Documentation    |     Premium Support

Image quality in PNG

Hello,


isn't it possible to define the quality when using  WebImageFormat.Png in RasterLayer.


 


Aren't you using System.Drawing.Bitmap to generate the images? Can't you define in EncoderParameters the Image Quality?


I'm getting large images, and can't use Jpeg because it need to have transparency. But i know that using System.Drawing i can specify the quality and so i can reduce the image size.


 


 



 


Rui,
As far as I know, the ImageCodeInfo and EncoderParameter doesn’t apply to PNG. PNG isn’t a lossy format, so Quality doesn’t  apply. We also did a test with the codes as following:
 
            Bitmap image = new Bitmap("car.png");
 
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            int j = 0;
            for (j = 0; j < codecs.Length; j++)
           {
                if (codecs[j].MimeType == "image/png") break;
            }
            EncoderParameter ratio = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 50L);
            EncoderParameters CodecParams = new EncoderParameters(1);
            CodecParams.Param[0] = ratio;
 
            
            image.Save(@"d:\dd.png",codecs[j],CodecParams);
 
We tried changes the second parameter of EncoderParameter, but there is no effect.
Sorry for the inconicence.
 
Johnny

Johny, you are right, my bad.


In the attachements i send some code. I was able to reduce 4,5 MB to 3,05 MB  18 tiles generated by ThinkGEO WebEdition.


I guess we can improve a little more, what do you say?


 



sThinkgeoPNG.zip (13.2 KB)

By the way, why do i get black background when using jpeg?

 


Rui,
I did the test with your code, but unable recreate what you mentioned. Here is the result:

The detail:

Additionally, It seem that the two images you posted don’t follow sample’s name rule. If the original image name is “A.png”, the name of converted image should be “out_A.png”, right? So please check the “out_3276411.png” is converted from “3276387.png”.

Thanks,
Johnny

 


Rui,
The Black area with Jpeg means the transparent in PNG format. If you have a .PNG image with transparent background, you will realize the background of the image will become black if you are gonna convert it to Jpg using GDI+.
Thanks,
Johnny

Johnny, 

with small images you will not be able to see the difference. I send you some images that were generated by WebEdition give it a try. 


"Additionally, It seem that the two  images you posted don’t follow sample’s name rule. If the original image  name is “A.png”, the name of converted image should be “out_A.png”,  right? So please check the “out_3276411.png” is converted from  “3276387.png”."

those are not the properties of an image, are the properties of 18 images. 


 




I understand that the black is the transparent on a PNG, what i can't understand is why when I add a mrSID or an ECW to the map I get those black areas, can them be forced to white or to other color?  

I haven't try other formats.



3276575.zip (356 KB)



 


Hi Rui,
Thanks for your advice, which indeed decrease the size of the image. In my mind, this is weird, PNG isn’t a lossy format. Do you know the reason?
 Now let’s turn back to your question “Define the quality when using PNG format”. As far as I know, you mean the quality of Cached image generated by TileCache, right? That’s a hard and complex stuff now, because the LayerOverlay used the ServerCache as property instead of TileCache.
One way is that we can overwrite the TileResourceSingleThread class, but it requires us to re-write all the logic about generating images. That’s very complex, I think.
Regarding the “Black background” issue, I was unable to recreate it, can you check whether you delete all the cached images before a new try? Here as following is my test code.

 


                Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.StandardColors.White);
                Map1.CurrentExtent = new RectangleShape(-80.5, 68.9, 80, -60.43);
                Map1.MapUnit = GeographyUnit.DecimalDegree;
 
                MrSidRasterLayer sidImageLayer = new MrSidRasterLayer(MapPath(@"~\SampleData\World\World.sid"));
                sidImageLayer.UpperThreshold = double.MaxValue;
                sidImageLayer.LowerThreshold = 0;
 
                Map1.StaticOverlay.ServerCache.CacheDirectory = "d:\\Temp";
                Map1.StaticOverlay.ServerCache.CacheId = "MRSid";
                Map1.StaticOverlay.Layers.Add(sidImageLayer);


 



Please check whether there is something different with yours.
 
Thanks,
Johnny
 

Hello Johnny,


I don't want to descrease size of cached images. The idea is that they are already cached in small format.


But if we manage to put the JPEG working good, it solves my problem.


 


I found out the main test case to raise the black background problem. You must put the overlay as a non base overlay.


 


 


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Map1.MapUnit = GeographyUnit.Meter

        Map1.MapBackground.BackgroundBrush = New GeoSolidBrush(GeoColor.StandardColors.White)

        Map1.MapTools.MouseCoordinate.Enabled = True

        Map1.MapTools.MouseCoordinate.MouseCoordinateType = MouseCoordinateType.LongitudeLatitude



        Map1.MapTools.Logo.Enabled = False

        Map1.MapTools.MiniMap.Enabled = True

        Map1.MapTools.OverlaySwitcher.Enabled = True



        Dim sidImageLayer As MrSidRasterLayer

        Dim sidOverlay As LayerOverlay = New LayerOverlay("SIDIMAGE", False, TileType.MultipleTile)

        sidImageLayer = New MrSidRasterLayer(MapPath("~/App_Data/cad_col_a.sid"))



        sidImageLayer.Open()

        Map1.CurrentExtent = sidImageLayer.GetBoundingBox()

        sidImageLayer.Close()



        sidImageLayer.UpperThreshold = Double.MaxValue

        sidImageLayer.LowerThreshold = 0

        sidOverlay.Layers.Add(sidImageLayer)

        sidOverlay.WebImageFormat = WebImageFormat.Jpeg



        Map1.CustomOverlays.Add(sidOverlay)




    End Sub


 


 



Hi Rui, 
 Here as following is the screenshot you get, right? It happened because we just create the Bitmap and draw the images on the Bitmap, in that case, the area with no images will become black background if we save it to JPEG. Here is sample code you can try: 
  
             Bitmap bmp = new Bitmap(256, 256); 
             bmp.Save(@"d:\c.jpeg", ImageFormat.Jpeg); 
  
 Additionaly, the DynamicOverlay(non-base Overlay) always lay on other overlay, it requires to be transparent,so we are unable to clear it with any other colors. 
  
 Thanks, 
 Johnny 
  


Ok Johnny i thought you were doing that way. But in case of JPEG was not better to be the same color as the mapbackground or being able to specify the background color? 
  
 We have some old cartography that must be shown on map overlapping each other. And since it was scanned is not very nice appear white and the black.  
  
 :(

Hi Rui,


We allow the JPEG as the backgroud layer of the map, also you can set the background color for it. But it's unble to set background color for non-baselayers, just as i mentioned, non-baselayer always lay on other layers, it need to be transparent, right? If you use JPEG format for non-base layer, the other layers under it will be invisible.


Can you detail your scenario? I'm curious why you need to set the background color for non-base layers.


Thanks,

Johnny


 



Hello Johnny, but haven’t you fixed this in version 4.0.118? 
  
 An example scenario is the following: 
 We have some municipality charts that are taken by areas. This charts are scanned. There is the need to see diferent combination of charts, they never overlap with each other and this combination must be dynamic, in other word, is the user who selects wich he want to see.  
  
 But now I realize that I need to find some way to specify the layer extents and only show those and not all map, or that white part will be on top of the previous chart.  
 I need to think a little more on how I’ll do that, but even so, it’s nice to have the option of specifying the JPEG background color.

 


Hi Rui,
I made the changes that the non-base overlay can be set background color in 4.0.118, but it proved that that’s not a good idea, and then made the code back. Sorry for the inconvenience.
Regarding your scenario, i think you can load all the municipality charts into base overlay and set the IsVisible property of each layer to control whether it’s visible in the Overlay. In that way, any more than two charts can be combined easily. Please let me know if I miss something.
Additionally, I’m still unable to understand why you said “it's nice to have the option of specifying the JPEG background color.”, do you mean you can resolve the problem if I made the changes? Can you let me know how to get it the non-base overlay allows to change the background color?
 
Thanks,
Johnny

Is not possible to say to a overlay to appear only in some extent is it? Like a window in the middle of the map, I don't know if I can make myself clear... 



Rui, 
 Yes, the overlay is a kind of div that covers the full view of the map instead of certain extent, that’s why I always say that it’s unable to resolve the problem even if the non-base overlay allows us to set the background color. Do you think the idea about adding all images into one Overlay, in that way the images just fill certain extents? It has been mentioned in last reply. 
  
 Thanks, 
 Johnny 


Adding all images in on overlay cannot be done.  
 'cause i need to change the visibility of some images to be able to compare things on map.

 


Hi Rui,
Do you mean that several images cover each other? It’s a little hard for me to imagine the image looks like. Can you give some screenshots? Or a small demo to forumsupport@thinkgeo.com.
Thanks,
Johnny