public static IntPtr GenerateHICON(ImageSource image, Size dimensions) { if (image == null) { return(IntPtr.Zero); } BitmapFrame bitmapFrame = image as BitmapFrame; if (bitmapFrame != null) { bitmapFrame = Utility.GetBestMatch(bitmapFrame.Decoder.Frames, (int)dimensions.Width, (int)dimensions.Height); } else { Rect rectangle = new Rect(0.0, 0.0, dimensions.Width, dimensions.Height); double num = dimensions.Width / dimensions.Height; double num2 = image.Width / image.Height; if (image.Width <= dimensions.Width && image.Height <= dimensions.Height) { rectangle = new Rect((dimensions.Width - image.Width) / 2.0, (dimensions.Height - image.Height) / 2.0, image.Width, image.Height); } else if (num > num2) { double num3 = image.Width / image.Height * dimensions.Width; rectangle = new Rect((dimensions.Width - num3) / 2.0, 0.0, num3, dimensions.Height); } else if (num < num2) { double num4 = image.Height / image.Width * dimensions.Height; rectangle = new Rect(0.0, (dimensions.Height - num4) / 2.0, dimensions.Width, num4); } DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); drawingContext.DrawImage(image, rectangle); drawingContext.Close(); RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)dimensions.Width, (int)dimensions.Height, 96.0, 96.0, PixelFormats.Pbgra32); renderTargetBitmap.Render(drawingVisual); bitmapFrame = BitmapFrame.Create(renderTargetBitmap); } IntPtr result; using (MemoryStream memoryStream = new MemoryStream()) { new PngBitmapEncoder { Frames = { bitmapFrame } }.Save(memoryStream); using (ManagedIStream managedIStream = new ManagedIStream(memoryStream)) { IntPtr zero = IntPtr.Zero; try { Status status = NativeMethods.GdipCreateBitmapFromStream(managedIStream, out zero); if (status != Status.Ok) { result = IntPtr.Zero; } else { IntPtr intPtr; status = NativeMethods.GdipCreateHICONFromBitmap(zero, out intPtr); if (status != Status.Ok) { result = IntPtr.Zero; } else { result = intPtr; } } } finally { Utility.SafeDisposeImage(ref zero); } } } return(result); }
public static IntPtr GenerateHICON(ImageSource image, Size dimensions) { if (image == null) { return(IntPtr.Zero); } // If we're getting this from a ".ico" resource, then it comes through as a BitmapFrame. // We can use leverage this as a shortcut to get the right 16x16 representation // because DrawImage doesn't do that for us. var bf = image as BitmapFrame; if (bf != null) { bf = GetBestMatch(bf.Decoder.Frames, ( int )dimensions.Width, ( int )dimensions.Height); } else { // Constrain the dimensions based on the aspect ratio. var drawingDimensions = new Rect(0, 0, dimensions.Width, dimensions.Height); // There's no reason to assume that the requested image dimensions are square. double renderRatio = dimensions.Width / dimensions.Height; double aspectRatio = image.Width / image.Height; // If it's smaller than the requested size, then place it in the middle and pad the image. if (image.Width <= dimensions.Width && image.Height <= dimensions.Height) { drawingDimensions = new Rect((dimensions.Width - image.Width) / 2, (dimensions.Height - image.Height) / 2, image.Width, image.Height); } else if (renderRatio > aspectRatio) { double scaledRenderWidth = (image.Width / image.Height) * dimensions.Width; drawingDimensions = new Rect((dimensions.Width - scaledRenderWidth) / 2, 0, scaledRenderWidth, dimensions.Height); } else if (renderRatio < aspectRatio) { double scaledRenderHeight = (image.Height / image.Width) * dimensions.Height; drawingDimensions = new Rect(0, (dimensions.Height - scaledRenderHeight) / 2, dimensions.Width, scaledRenderHeight); } var dv = new DrawingVisual(); DrawingContext dc = dv.RenderOpen(); dc.DrawImage(image, drawingDimensions); dc.Close(); var bmp = new RenderTargetBitmap(( int )dimensions.Width, ( int )dimensions.Height, 96, 96, PixelFormats.Pbgra32); bmp.Render(dv); bf = BitmapFrame.Create(bmp); } // Using GDI+ to convert to an HICON. // I'd rather not duplicate their code. using (MemoryStream memstm = new MemoryStream()) { BitmapEncoder enc = new PngBitmapEncoder(); enc.Frames.Add(bf); enc.Save(memstm); using (var istm = new ManagedIStream(memstm)) { // We are not bubbling out GDI+ errors when creating the native image fails. IntPtr bitmap = IntPtr.Zero; try { Status gpStatus = NativeMethods.GdipCreateBitmapFromStream(istm, out bitmap); if (Status.Ok != gpStatus) { return(IntPtr.Zero); } IntPtr hicon; gpStatus = NativeMethods.GdipCreateHICONFromBitmap(bitmap, out hicon); if (Status.Ok != gpStatus) { return(IntPtr.Zero); } // Caller is responsible for freeing this. return(hicon); } finally { Utility.SafeDisposeImage(ref bitmap); } } } }
public static IntPtr GenerateHICON(ImageSource image, Size dimensions) { IntPtr intPtr; IntPtr zero; if (image == null) { return(IntPtr.Zero); } BitmapFrame bestMatch = image as BitmapFrame; if (bestMatch == null) { Rect rect = new Rect(0, 0, dimensions.Width, dimensions.Height); double width = dimensions.Width / dimensions.Height; double num = image.Width / image.Height; if (image.Width <= dimensions.Width && image.Height <= dimensions.Height) { rect = new Rect((dimensions.Width - image.Width) / 2, (dimensions.Height - image.Height) / 2, image.Width, image.Height); } else if (width > num) { double width1 = image.Width / image.Height * dimensions.Width; rect = new Rect((dimensions.Width - width1) / 2, 0, width1, dimensions.Height); } else if (width < num) { double height = image.Height / image.Width * dimensions.Height; rect = new Rect(0, (dimensions.Height - height) / 2, dimensions.Width, height); } DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); drawingContext.DrawImage(image, rect); drawingContext.Close(); RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)dimensions.Width, (int)dimensions.Height, 96, 96, PixelFormats.Pbgra32); renderTargetBitmap.Render(drawingVisual); bestMatch = BitmapFrame.Create(renderTargetBitmap); } else { bestMatch = Utility.GetBestMatch(bestMatch.Decoder.Frames, (int)dimensions.Width, (int)dimensions.Height); } using (MemoryStream memoryStream = new MemoryStream()) { BitmapEncoder pngBitmapEncoder = new PngBitmapEncoder(); pngBitmapEncoder.Frames.Add(bestMatch); pngBitmapEncoder.Save(memoryStream); using (ManagedIStream managedIStream = new ManagedIStream(memoryStream)) { IntPtr zero1 = IntPtr.Zero; try { if (Standard.NativeMethods.GdipCreateBitmapFromStream(managedIStream, out zero1) == Status.Ok) { zero = (Standard.NativeMethods.GdipCreateHICONFromBitmap(zero1, out intPtr) == Status.Ok ? intPtr : IntPtr.Zero); } else { zero = IntPtr.Zero; } } finally { Utility.SafeDisposeImage(ref zero1); } } } return(zero); }