123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT license.
- // See the LICENSE file in the project root for more information.
- //
- // Purpose: ImageLoader utility class loads specified image and
- // caches it in the memory for the future use.
- //
- using System;
- using System.Collections;
- using System.ComponentModel;
- using System.ComponentModel.Design;
- using System.Drawing;
- using System.IO;
- using System.Net;
- using System.Reflection;
- using System.Resources;
- using System.Security;
- namespace FastReport.DataVisualization.Charting.Utilities
- {
- using Size = System.Drawing.Size;
- /// <summary>
- /// 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.
- /// </summary>
- 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
- /// <summary>
- /// Default constructor is not accessible.
- /// </summary>
- private ImageLoader()
- {
- }
- /// <summary>
- /// Default public constructor.
- /// </summary>
- /// <param name="container">Service container.</param>
- public ImageLoader(IServiceContainer container)
- {
- if(container == null)
- {
- throw(new ArgumentNullException(SR.ExceptionImageLoaderInvalidServiceContainer));
- }
- _serviceContainer = container;
- }
- /// <summary>
- /// Returns Image Loader service object
- /// </summary>
- /// <param name="serviceType">Requested service type.</param>
- /// <returns>Image Loader service object.</returns>
- [EditorBrowsableAttribute(EditorBrowsableState.Never)]
- object IServiceProvider.GetService(Type serviceType)
- {
- if(serviceType == typeof(ImageLoader))
- {
- return this;
- }
- throw (new ArgumentException( SR.ExceptionImageLoaderUnsupportedType( serviceType.ToString())));
- }
- /// <summary>
- /// Dispose images in the hashtable
- /// </summary>
- 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
- /// <summary>
- /// Loads image from URL. Checks if image already loaded (cached).
- /// </summary>
- /// <param name="imageURL">Image name (FileName, URL, Resource).</param>
- /// <returns>Image object.</returns>
- public System.Drawing.Image LoadImage(string imageURL)
- {
- return LoadImage(imageURL, true);
- }
-
- /// <summary>
- /// Loads image from URL. Checks if image already loaded (cached).
- /// </summary>
- /// <param name="imageURL">Image name (FileName, URL, Resource).</param>
- /// <param name="saveImage">True if loaded image should be saved in cache.</param>
- /// <returns>Image object</returns>
- 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];
- }
- // 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));
- }
- 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;
- }
- }
- }
- }
- }
- }
- 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)
- {
- }
- }
- }
- // 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);
- }
- // Error loading image
- if(image == null)
- {
- throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageLocation( imageURL ) ) );
- }
- // Save new image in cache
- if(saveImage)
- {
- _imageData[imageURL] = image;
- }
- return image;
- }
- /// <summary>
- /// Helper function which loads image from file.
- /// </summary>
- /// <param name="fileName">File name.</param>
- /// <returns>Loaded image or null.</returns>
- private System.Drawing.Image LoadFromFile(string fileName)
- {
- // Try to load image from file
- try
- {
- return System.Drawing.Image.FromFile(fileName);
- }
- catch(FileNotFoundException)
- {
- return null;
- }
- }
- /// <summary>
- /// Returns the image size taking the image DPI into consideration.
- /// </summary>
- /// <param name="name">Image name (FileName, URL, Resource).</param>
- /// <param name="graphics">Graphics used to calculate the image size.</param>
- /// <param name="size">Calculated size.</param>
- /// <returns>false if it fails to calculate the size, otherwise true.</returns>
- internal bool GetAdjustedImageSize(string name, IGraphics graphics, ref SizeF size)
- {
- Image image = LoadImage(name);
- if (image == null)
- return false;
- GetAdjustedImageSize(image, graphics, ref size);
- return true;
- }
- /// <summary>
- /// Returns the image size taking the image DPI into consideration.
- /// </summary>
- /// <param name="image">Image for whcih to calculate the size.</param>
- /// <param name="graphics">Graphics used to calculate the image size.</param>
- /// <param name="size">Calculated size.</param>
- internal static void GetAdjustedImageSize(Image image, IGraphics 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;
- }
- }
- /// <summary>
- /// Checks if the image has the same DPI as the graphics object.
- /// </summary>
- /// <param name="image">Image to be checked.</param>
- /// <param name="graphics">Graphics object to be used.</param>
- /// <returns>true if they match, otherwise false.</returns>
- internal static bool DoDpisMatch(Image image, IGraphics graphics)
- {
- return graphics.DpiX == image.HorizontalResolution && graphics.DpiY == image.VerticalResolution;
- }
- internal static Image GetScaledImage(Image image, IGraphics 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
- }
- }
|