Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Web.DataVisualization / Common / Utilities / ImageLoader.cs
blob1b07b467c2fa41d8a5d2a7adb2b4a7c4f59db89c
1 //-------------------------------------------------------------
2 // <copyright company=’Microsoft Corporation’>
3 // Copyright © Microsoft Corporation. All Rights Reserved.
4 // </copyright>
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 // File: ImageLoader.cs
9 //
10 // Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Utilities
12 // Classes: ImageLoader
14 // Purpose: ImageLoader utility class loads specified image and
15 // caches it in the memory for the future use.
16 //
17 // Images can be loaded from different places including
18 // Files, URIs, WebRequests and Control Resources.
20 // Reviewed: AG - August 7, 2002
21 // AG - Microsoft 5, 2007
23 //===================================================================
26 #region Used Namespaces
28 using System;
29 using System.Drawing;
30 using System.Collections;
31 using System.ComponentModel;
32 using System.ComponentModel.Design;
33 using System.Reflection;
34 using System.Net;
35 using System.IO;
36 using System.Security;
37 using System.Resources;
39 #if Microsoft_CONTROL
40 using System.Windows.Forms.DataVisualization.Charting;
41 #else
42 using System.Web;
43 using System.Web.UI.DataVisualization.Charting;
44 #endif
46 #endregion
48 #if Microsoft_CONTROL
49 namespace System.Windows.Forms.DataVisualization.Charting.Utilities
50 #else
51 namespace System.Web.UI.DataVisualization.Charting.Utilities
52 #endif
54 /// <summary>
55 /// ImageLoader utility class loads and returns specified image
56 /// form the File, URI, Web Request or Chart Resources.
57 /// Loaded images are stored in the internal hashtable which
58 /// allows to improve performance if image need to be used
59 /// several times.
60 /// </summary>
61 internal class ImageLoader : IDisposable, IServiceProvider
63 #region Fields
65 // Image storage
66 private Hashtable _imageData = null;
68 // Reference to the service container
69 private IServiceContainer _serviceContainer = null;
71 #endregion
73 #region Constructors and Initialization
75 /// <summary>
76 /// Default constructor is not accessible.
77 /// </summary>
78 private ImageLoader()
82 /// <summary>
83 /// Default public constructor.
84 /// </summary>
85 /// <param name="container">Service container.</param>
86 public ImageLoader(IServiceContainer container)
88 if(container == null)
90 throw(new ArgumentNullException(SR.ExceptionImageLoaderInvalidServiceContainer));
92 _serviceContainer = container;
95 /// <summary>
96 /// Returns Image Loader service object
97 /// </summary>
98 /// <param name="serviceType">Requested service type.</param>
99 /// <returns>Image Loader service object.</returns>
100 [EditorBrowsableAttribute(EditorBrowsableState.Never)]
101 object IServiceProvider.GetService(Type serviceType)
103 if(serviceType == typeof(ImageLoader))
105 return this;
107 throw (new ArgumentException( SR.ExceptionImageLoaderUnsupportedType( serviceType.ToString())));
110 /// <summary>
111 /// Dispose images in the hashtable
112 /// </summary>
113 public void Dispose()
115 if (_imageData != null)
117 foreach (DictionaryEntry entry in _imageData)
119 if (entry.Value is IDisposable)
121 ((IDisposable)entry.Value).Dispose();
124 _imageData = null;
125 GC.SuppressFinalize(this);
129 #endregion
131 #region Methods
133 /// <summary>
134 /// Loads image from URL. Checks if image already loaded (cached).
135 /// </summary>
136 /// <param name="imageURL">Image name (FileName, URL, Resource).</param>
137 /// <returns>Image object.</returns>
138 public System.Drawing.Image LoadImage(string imageURL)
140 return LoadImage(imageURL, true);
143 /// <summary>
144 /// Loads image from URL. Checks if image already loaded (cached).
145 /// </summary>
146 /// <param name="imageURL">Image name (FileName, URL, Resource).</param>
147 /// <param name="saveImage">True if loaded image should be saved in cache.</param>
148 /// <returns>Image object</returns>
149 public System.Drawing.Image LoadImage(string imageURL, bool saveImage)
151 System.Drawing.Image image = null;
153 // Check if image is defined in the chart image collection
154 if (_serviceContainer != null)
156 Chart chart = (Chart)_serviceContainer.GetService(typeof(Chart));
157 if(chart != null)
159 foreach(NamedImage namedImage in chart.Images)
161 if(namedImage.Name == imageURL)
163 return namedImage.Image;
169 // Create new hashtable
170 if (_imageData == null)
172 _imageData = new Hashtable(StringComparer.OrdinalIgnoreCase);
175 // First check if image with this name already loaded
176 if (_imageData.Contains(imageURL))
178 image = (System.Drawing.Image)_imageData[imageURL];
181 #if ! Microsoft_CONTROL
183 // Try to load as relative URL using the Control object
184 if(image == null)
186 Chart control = (Chart)_serviceContainer.GetService(typeof(Chart));
187 if (control != null && control.Page != null)
189 if (!control.IsDesignMode())
191 image = LoadFromFile(control.Page.MapPath(imageURL));
193 else if (control.IsDesignMode() && !String.IsNullOrEmpty(control.webFormDocumentURL))
195 // Find current web page path and fileName
196 Uri pageUri = new Uri(control.webFormDocumentURL);
197 string path = pageUri.LocalPath;
198 string pageFile = pageUri.Segments[pageUri.Segments.Length-1];
200 // Find full image fileName
201 string imageFileRelative = control.ResolveClientUrl(imageURL);
202 string imageFile = path.Replace(pageFile, imageFileRelative);
204 // Load image
205 image = LoadFromFile(imageFile);
209 else if ( HttpContext.Current != null )
211 image = LoadFromFile(HttpContext.Current.Request.MapPath(imageURL));
214 #endif
216 // Try to load image from resource
217 if(image == null)
222 // Check if resource class type was specified
223 int columnIndex = imageURL.IndexOf("::", StringComparison.Ordinal);
224 if (columnIndex > 0)
226 string resourceRootName = imageURL.Substring(0, columnIndex);
227 string resourceName = imageURL.Substring(columnIndex + 2);
228 System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(resourceRootName, Assembly.GetExecutingAssembly());
229 image = (System.Drawing.Image)(resourceManager.GetObject(resourceName));
231 #if Microsoft_CONTROL
232 else if (Assembly.GetEntryAssembly() != null)
234 // Check if resource class type was specified
235 columnIndex = imageURL.IndexOf(':');
236 if (columnIndex > 0)
238 string resourceRootName = imageURL.Substring(0, columnIndex);
239 string resourceName = imageURL.Substring(columnIndex + 1);
240 System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(resourceRootName, Assembly.GetEntryAssembly());
241 image = (Image)(resourceManager.GetObject(resourceName));
243 else
245 // Try to load resource from every type defined in entry assembly
246 Assembly entryAssembly = Assembly.GetEntryAssembly();
247 if (entryAssembly != null)
249 foreach (Type type in entryAssembly.GetTypes())
251 System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(type);
254 image = (Image)(resourceManager.GetObject(imageURL));
256 catch (ArgumentNullException)
259 catch (MissingManifestResourceException)
263 // Check if image was loaded
264 if (image != null)
266 break;
272 #endif
274 catch (MissingManifestResourceException)
280 // Try to load image using the Web Request
281 if(image == null)
283 Uri imageUri = null;
284 try
286 // Try to create URI directly from image URL (will work in case of absolute URL)
287 imageUri = new Uri(imageURL);
289 catch(UriFormatException)
293 // Load image from file or web resource
294 if(imageUri != null)
298 WebRequest request = WebRequest.Create(imageUri);
299 image = System.Drawing.Image.FromStream(request.GetResponse().GetResponseStream());
301 catch (ArgumentException)
304 catch (NotSupportedException)
307 catch (SecurityException)
312 #if Microsoft_CONTROL
313 // absolute uri(without Server.MapPath)in web is not allowed. Loading from replative uri Server[Page].MapPath is done above.
314 // Try to load as file
315 if(image == null)
318 image = LoadFromFile(imageURL);
320 #endif
322 // Error loading image
323 if(image == null)
325 #if ! Microsoft_CONTROL
326 throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageUrl( imageURL ) ) );
327 #else
328 throw(new ArgumentException( SR.ExceptionImageLoaderIncorrectImageLocation( imageURL ) ) );
329 #endif
332 // Save new image in cache
333 if(saveImage)
335 _imageData[imageURL] = image;
338 return image;
341 /// <summary>
342 /// Helper function which loads image from file.
343 /// </summary>
344 /// <param name="fileName">File name.</param>
345 /// <returns>Loaded image or null.</returns>
346 private System.Drawing.Image LoadFromFile(string fileName)
348 // Try to load image from file
351 return System.Drawing.Image.FromFile(fileName);
353 catch(FileNotFoundException)
355 return null;
359 /// <summary>
360 /// Returns the image size taking the image DPI into consideration.
361 /// </summary>
362 /// <param name="name">Image name (FileName, URL, Resource).</param>
363 /// <param name="graphics">Graphics used to calculate the image size.</param>
364 /// <param name="size">Calculated size.</param>
365 /// <returns>false if it fails to calculate the size, otherwise true.</returns>
366 internal bool GetAdjustedImageSize(string name, Graphics graphics, ref SizeF size)
368 Image image = LoadImage(name);
370 if (image == null)
371 return false;
373 GetAdjustedImageSize(image, graphics, ref size);
375 return true;
378 /// <summary>
379 /// Returns the image size taking the image DPI into consideration.
380 /// </summary>
381 /// <param name="image">Image for whcih to calculate the size.</param>
382 /// <param name="graphics">Graphics used to calculate the image size.</param>
383 /// <param name="size">Calculated size.</param>
384 internal static void GetAdjustedImageSize(Image image, Graphics graphics, ref SizeF size)
386 if (graphics != null)
388 //this will work in case the image DPI is specified, otherwise the image DPI will be assumed to be same as the screen DPI
389 size.Width = image.Width * graphics.DpiX / image.HorizontalResolution;
390 size.Height = image.Height * graphics.DpiY / image.VerticalResolution;
392 else
394 size.Width = image.Width;
395 size.Height = image.Height;
399 /// <summary>
400 /// Checks if the image has the same DPI as the graphics object.
401 /// </summary>
402 /// <param name="image">Image to be checked.</param>
403 /// <param name="graphics">Graphics object to be used.</param>
404 /// <returns>true if they match, otherwise false.</returns>
405 internal static bool DoDpisMatch(Image image, Graphics graphics)
407 return graphics.DpiX == image.HorizontalResolution && graphics.DpiY == image.VerticalResolution;
410 internal static Image GetScaledImage(Image image, Graphics graphics)
412 Bitmap scaledImage = new Bitmap(image, new Size((int)(image.Width * graphics.DpiX / image.HorizontalResolution),
413 (int)(image.Height * graphics.DpiY / image.VerticalResolution)));
415 return scaledImage;
419 #endregion