//------------------------------------------------------------- // // Copyright © Microsoft Corporation. All Rights Reserved. // //------------------------------------------------------------- // @owner=alexgor, deliant //================================================================= // File: ImageLoader.cs // // Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Utilities // // Classes: ImageLoader // // Purpose: ImageLoader utility class loads specified image and // caches it in the memory for the future use. // // Images can be loaded from different places including // Files, URIs, WebRequests and Control Resources. // // Reviewed: AG - August 7, 2002 // AG - Microsoft 5, 2007 // //=================================================================== #region Used Namespaces using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Reflection; using System.Net; using System.IO; using System.Security; using System.Resources; #if Microsoft_CONTROL using System.Windows.Forms.DataVisualization.Charting; #else using System.Web; using System.Web.UI.DataVisualization.Charting; #endif #endregion #if Microsoft_CONTROL namespace System.Windows.Forms.DataVisualization.Charting.Utilities #else namespace System.Web.UI.DataVisualization.Charting.Utilities #endif { /// /// ImageLoader utility class loads and returns specified image /// form the File, URI, Web Request or Chart Resources. /// Loaded images are stored in the internal hashtable which /// allows to improve performance if image need to be used /// several times. /// internal class ImageLoader : IDisposable, IServiceProvider { #region Fields // Image storage private Hashtable _imageData = null; // Reference to the service container private IServiceContainer _serviceContainer = null; #endregion #region Constructors and Initialization /// /// Default constructor is not accessible. /// private ImageLoader() { } /// /// Default public constructor. /// /// Service container. public ImageLoader(IServiceContainer container) { if(container == null) { throw(new ArgumentNullException(SR.ExceptionImageLoaderInvalidServiceContainer)); } _serviceContainer = container; } /// /// Returns Image Loader service object /// /// Requested service type. /// Image Loader service object. [EditorBrowsableAttribute(EditorBrowsableState.Never)] object IServiceProvider.GetService(Type serviceType) { if(serviceType == typeof(ImageLoader)) { return this; } throw (new ArgumentException( SR.ExceptionImageLoaderUnsupportedType( serviceType.ToString()))); } /// /// Dispose images in the hashtable /// public void Dispose() { if (_imageData != null) { foreach (DictionaryEntry entry in _imageData) { if (entry.Value is IDisposable) { ((IDisposable)entry.Value).Dispose(); } } _imageData = null; GC.SuppressFinalize(this); } } #endregion #region Methods /// /// Loads image from URL. Checks if image already loaded (cached). /// /// Image name (FileName, URL, Resource). /// Image object. public System.Drawing.Image LoadImage(string imageURL) { return LoadImage(imageURL, true); } /// /// Loads image from URL. Checks if image already loaded (cached). /// /// Image name (FileName, URL, Resource). /// True if loaded image should be saved in cache. /// Image object public System.Drawing.Image LoadImage(string imageURL, bool saveImage) { System.Drawing.Image image = null; // Check if image is defined in the chart image collection if (_serviceContainer != null) { Chart chart = (Chart)_serviceContainer.GetService(typeof(Chart)); if(chart != null) { foreach(NamedImage namedImage in chart.Images) { if(namedImage.Name == imageURL) { return namedImage.Image; } } } } // Create new hashtable if (_imageData == null) { _imageData = new Hashtable(StringComparer.OrdinalIgnoreCase); } // First check if image with this name already loaded if (_imageData.Contains(imageURL)) { image = (System.Drawing.Image)_imageData[imageURL]; } #if ! Microsoft_CONTROL // Try to load as relative URL using the Control object if(image == null) { Chart control = (Chart)_serviceContainer.GetService(typeof(Chart)); if (control != null && control.Page != null) { if (!control.IsDesignMode()) { image = LoadFromFile(control.Page.MapPath(imageURL)); } else if (control.IsDesignMode() && !String.IsNullOrEmpty(control.webFormDocumentURL)) { // Find current web page path and fileName Uri pageUri = new Uri(control.webFormDocumentURL); string path = pageUri.LocalPath; string pageFile = pageUri.Segments[pageUri.Segments.Length-1]; // Find full image fileName string imageFileRelative = control.ResolveClientUrl(imageURL); string imageFile = path.Replace(pageFile, imageFileRelative); // Load image image = LoadFromFile(imageFile); } } else if ( HttpContext.Current != null ) { image = LoadFromFile(HttpContext.Current.Request.MapPath(imageURL)); } } #endif // Try to load image from resource if(image == null) { try { // Check if resource class type was specified int columnIndex = imageURL.IndexOf("::", StringComparison.Ordinal); if (columnIndex > 0) { string resourceRootName = imageURL.Substring(0, columnIndex); string resourceName = imageURL.Substring(columnIndex + 2); System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(resourceRootName, Assembly.GetExecutingAssembly()); image = (System.Drawing.Image)(resourceManager.GetObject(resourceName)); } #if Microsoft_CONTROL else if (Assembly.GetEntryAssembly() != null) { // Check if resource class type was specified columnIndex = imageURL.IndexOf(':'); if (columnIndex > 0) { string resourceRootName = imageURL.Substring(0, columnIndex); string resourceName = imageURL.Substring(columnIndex + 1); System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(resourceRootName, Assembly.GetEntryAssembly()); image = (Image)(resourceManager.GetObject(resourceName)); } else { // Try to load resource from every type defined in entry assembly Assembly entryAssembly = Assembly.GetEntryAssembly(); if (entryAssembly != null) { foreach (Type type in entryAssembly.GetTypes()) { System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(type); try { image = (Image)(resourceManager.GetObject(imageURL)); } catch (ArgumentNullException) { } catch (MissingManifestResourceException) { } // Check if image was loaded if (image != null) { break; } } } } } #endif } catch (MissingManifestResourceException) { } } // Try to load image using the Web Request if(image == null) { Uri imageUri = null; try { // Try to create URI directly from image URL (will work in case of absolute URL) imageUri = new Uri(imageURL); } catch(UriFormatException) {} // Load image from file or web resource if(imageUri != null) { try { WebRequest request = WebRequest.Create(imageUri); image = System.Drawing.Image.FromStream(request.GetResponse().GetResponseStream()); } catch (ArgumentException) { } catch (NotSupportedException) { } catch (SecurityException) { } } } #if Microsoft_CONTROL // absolute uri(without Server.MapPath)in web is not allowed. Loading from replative uri Server[Page].MapPath is done above. // Try to load as file if(image == null) { image = LoadFromFile(imageURL); } #endif // Error loading image if(image == null) { #if ! Microsoft_CONTROL throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageUrl( imageURL ) ) ); #else throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageLocation( imageURL ) ) ); #endif } // Save new image in cache if(saveImage) { _imageData[imageURL] = image; } return image; } /// /// Helper function which loads image from file. /// /// File name. /// Loaded image or null. private System.Drawing.Image LoadFromFile(string fileName) { // Try to load image from file try { return System.Drawing.Image.FromFile(fileName); } catch(FileNotFoundException) { return null; } } /// /// Returns the image size taking the image DPI into consideration. /// /// Image name (FileName, URL, Resource). /// Graphics used to calculate the image size. /// Calculated size. /// false if it fails to calculate the size, otherwise true. internal bool GetAdjustedImageSize(string name, Graphics graphics, ref SizeF size) { Image image = LoadImage(name); if (image == null) return false; GetAdjustedImageSize(image, graphics, ref size); return true; } /// /// Returns the image size taking the image DPI into consideration. /// /// Image for whcih to calculate the size. /// Graphics used to calculate the image size. /// Calculated size. internal static void GetAdjustedImageSize(Image image, Graphics graphics, ref SizeF size) { if (graphics != null) { //this will work in case the image DPI is specified, otherwise the image DPI will be assumed to be same as the screen DPI size.Width = image.Width * graphics.DpiX / image.HorizontalResolution; size.Height = image.Height * graphics.DpiY / image.VerticalResolution; } else { size.Width = image.Width; size.Height = image.Height; } } /// /// Checks if the image has the same DPI as the graphics object. /// /// Image to be checked. /// Graphics object to be used. /// true if they match, otherwise false. internal static bool DoDpisMatch(Image image, Graphics graphics) { return graphics.DpiX == image.HorizontalResolution && graphics.DpiY == image.VerticalResolution; } internal static Image GetScaledImage(Image image, Graphics graphics) { Bitmap scaledImage = new Bitmap(image, new Size((int)(image.Width * graphics.DpiX / image.HorizontalResolution), (int)(image.Height * graphics.DpiY / image.VerticalResolution))); return scaledImage; } #endregion } }