locked
WPF Manipulating DPI of Images RRS feed

  • Question

  • So I have a .NET 4.0 WPF applicaton that does some image manipulation. Things like scales the image if it is too large. One thing I wanted it to do was update the DPI of an image if it was not 96 x 96. Below is the basic code that I was using, hard coded to a specific input and output image. It works great on almost all images that I update the DPI of, but it does not work on a few images for some reason. http://i48.tinypic.com/34sff5s.png is an example of the image that doesn't work. The DPI of the output image is something like 95.98... (you may have to look at the output image in something like GIMP to get the true DPI, windows explorer file details rounds the DPI to 96).

    Any ideas on what I might be doing wrong? Am I in trouble because I tried using the WPF image objects instead of the old image objects?

       
     private static void ResizeAndOpenImage()
            {            
                using (MemoryStream ms = new MemoryStream())
                {
                    using (FileStream fs = File.OpenRead(@"C:\Test\Images\34sff5s.png"))
                    {
                        //get the decoder for this extension                
                        PngBitmapDecoder decoder = new PngBitmapDecoder(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                        if (decoder != null)
                        {
                            BitmapSource sourceToResize = decoder.Frames.First();
                            //check if the DPI is less than 96, if so, resize it to 96
                            if (sourceToResize.DpiX != 96 || sourceToResize.DpiY != 96)
                            {
                                double dpi = 96;
                                int width = sourceToResize.PixelWidth;
                                int height = sourceToResize.PixelHeight;
    
                                int stride = width * 4; // 4 bytes per pixel
                                byte[] pixelData = new byte[stride * height];
                                sourceToResize.CopyPixels(pixelData, stride, 0);
    
                                sourceToResize = BitmapSource.Create(width, height, dpi, dpi, sourceToResize.Format, null, pixelData, stride);
    
                                using (FileStream destinationStream = new FileStream(@"C:\Test\Results\34sff5s.png", FileMode.Create))
                                {
                                    PngBitmapEncoder encoder = new PngBitmapEncoder();
                                    encoder.Frames.Add(BitmapFrame.Create(sourceToResize));
                                    encoder.Save(destinationStream);                                
                                }                      
                            }
                        }
                    }
                }            
            }

    • Edited by UWSkeletor Friday, October 5, 2012 2:46 PM
    Friday, October 5, 2012 2:44 PM

Answers

  • Hi UWSkeletor,

    I don't think you did it wrong, actually, what you state is a normal behavior. Pixel is calculated by integer,  Computer will round the float to integer even though you caclulate the DPI in float. Do 95.98 get from the GIMP tool? As I know, some tool may not provide rounded numbers.

    Have a nice day,


    Kee Poppy [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Kee Poppy Wednesday, October 24, 2012 9:54 AM
    Wednesday, October 10, 2012 3:48 AM