none
Bitmap.MakeTransparent changes resolution RRS feed

  • Question

  • Hi

    I am using Bitmap.MakeTransparent to make some part of image as transparent. What I noticed that after calling this method the resolution of my image changes.

    The way I use this is as below

    Bitmap bit = new Bitmap(memoryStrem);

    //Check resoltion it is 96

    bit.MakeTransparent(System.Drawing.Color.Black);

    //Again check resolution it changes to 120.

    This happens only when I explictly change my Windows DPI setting to 125 % instead of normal 100%.

    Regards

    JC

    Friday, June 14, 2013 9:51 AM

Answers

  • Or observation is correct, the function MakeTransparent makes a duplicate of the same size, but not taking over any other properties. So the result is using the display resolution which is 120dpi in your case.

    Only work around I can see is setting the resolution again after calling the MakeTransparent function by calling SetResolution.

    This is what MakeTransparent does (coming from reference source):

            /// <include file='doc\Bitmap.uex' path='docs/doc[@for="Bitmap.MakeTransparent1"]/*' />
            /// <devdoc> 
            ///    Makes the specified color transparent 
            ///    for this <see cref='System.Drawing.Bitmap'/>.
            /// </devdoc> 
            [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
            [ResourceExposure(ResourceScope.None)]
            [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
            public void MakeTransparent(Color transparentColor) { 
                if (RawFormat.Guid == ImageFormat.Icon.Guid) {
                    throw new InvalidOperationException(SR.GetString(SR.CantMakeIconTransparent)); 
                } 
    
                Size size = Size; 
    
                // The new bitmap must be in 32bppARGB  format, because that's the only
                // thing that supports alpha.  (And that's what the image is initialized to -- transparent)
                Bitmap result = null; 
                Graphics graphics = null;
                try { 
                    result = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb); 
                    try {
                        graphics = Graphics.FromImage(result); 
                        graphics.Clear(Color.Transparent);
                        Rectangle rectangle = new Rectangle(0,0, size.Width, size.Height);
    
                        ImageAttributes attributes = null; 
                        try {
                            attributes = new ImageAttributes(); 
                            attributes.SetColorKey(transparentColor, transparentColor); 
                            graphics.DrawImage(this, rectangle,
                                               0,0, size.Width, size.Height, 
                                               GraphicsUnit.Pixel, attributes, null, IntPtr.Zero);
                        }
                        finally {
                            if (attributes != null) { 
                                attributes.Dispose();
                            } 
                        } 
                    }
                    finally { 
                        if (graphics != null) {
                            graphics.Dispose();
                        }
                    } 
    
                    // Swap nativeImage pointers to make it look like we modified the image in place 
                    IntPtr temp = this.nativeImage; 
                    this.nativeImage = result.nativeImage;
                    result.nativeImage = temp; 
                }
                finally {
                    if (result != null) {
                        result.Dispose(); 
                    }
     
                } 
            }
    

    Friday, June 14, 2013 12:30 PM
  • Everything is correct 1.25 * 96 = 120.  To reset the desired display size of the image, reset the resolution to 96.
    Friday, June 14, 2013 7:35 PM

All replies

  • Or observation is correct, the function MakeTransparent makes a duplicate of the same size, but not taking over any other properties. So the result is using the display resolution which is 120dpi in your case.

    Only work around I can see is setting the resolution again after calling the MakeTransparent function by calling SetResolution.

    This is what MakeTransparent does (coming from reference source):

            /// <include file='doc\Bitmap.uex' path='docs/doc[@for="Bitmap.MakeTransparent1"]/*' />
            /// <devdoc> 
            ///    Makes the specified color transparent 
            ///    for this <see cref='System.Drawing.Bitmap'/>.
            /// </devdoc> 
            [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
            [ResourceExposure(ResourceScope.None)]
            [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
            public void MakeTransparent(Color transparentColor) { 
                if (RawFormat.Guid == ImageFormat.Icon.Guid) {
                    throw new InvalidOperationException(SR.GetString(SR.CantMakeIconTransparent)); 
                } 
    
                Size size = Size; 
    
                // The new bitmap must be in 32bppARGB  format, because that's the only
                // thing that supports alpha.  (And that's what the image is initialized to -- transparent)
                Bitmap result = null; 
                Graphics graphics = null;
                try { 
                    result = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb); 
                    try {
                        graphics = Graphics.FromImage(result); 
                        graphics.Clear(Color.Transparent);
                        Rectangle rectangle = new Rectangle(0,0, size.Width, size.Height);
    
                        ImageAttributes attributes = null; 
                        try {
                            attributes = new ImageAttributes(); 
                            attributes.SetColorKey(transparentColor, transparentColor); 
                            graphics.DrawImage(this, rectangle,
                                               0,0, size.Width, size.Height, 
                                               GraphicsUnit.Pixel, attributes, null, IntPtr.Zero);
                        }
                        finally {
                            if (attributes != null) { 
                                attributes.Dispose();
                            } 
                        } 
                    }
                    finally { 
                        if (graphics != null) {
                            graphics.Dispose();
                        }
                    } 
    
                    // Swap nativeImage pointers to make it look like we modified the image in place 
                    IntPtr temp = this.nativeImage; 
                    this.nativeImage = result.nativeImage;
                    result.nativeImage = temp; 
                }
                finally {
                    if (result != null) {
                        result.Dispose(); 
                    }
     
                } 
            }
    

    Friday, June 14, 2013 12:30 PM
  • Everything is correct 1.25 * 96 = 120.  To reset the desired display size of the image, reset the resolution to 96.
    Friday, June 14, 2013 7:35 PM