1 //-------------------------------------------------------------
2 // <copyright company=’Microsoft Corporation’>
3 // Copyright © Microsoft Corporation. All Rights Reserved.
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 // File: ImageLoader.cs
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.
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
30 using System
.Collections
;
31 using System
.ComponentModel
;
32 using System
.ComponentModel
.Design
;
33 using System
.Reflection
;
36 using System
.Security
;
37 using System
.Resources
;
40 using System
.Windows
.Forms
.DataVisualization
.Charting
;
43 using System
.Web
.UI
.DataVisualization
.Charting
;
49 namespace System
.Windows
.Forms
.DataVisualization
.Charting
.Utilities
51 namespace System
.Web
.UI
.DataVisualization
.Charting
.Utilities
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
61 internal class ImageLoader
: IDisposable
, IServiceProvider
66 private Hashtable _imageData
= null;
68 // Reference to the service container
69 private IServiceContainer _serviceContainer
= null;
73 #region Constructors and Initialization
76 /// Default constructor is not accessible.
83 /// Default public constructor.
85 /// <param name="container">Service container.</param>
86 public ImageLoader(IServiceContainer container
)
90 throw(new ArgumentNullException(SR
.ExceptionImageLoaderInvalidServiceContainer
));
92 _serviceContainer
= container
;
96 /// Returns Image Loader service object
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
))
107 throw (new ArgumentException( SR
.ExceptionImageLoaderUnsupportedType( serviceType
.ToString())));
111 /// Dispose images in the hashtable
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();
125 GC
.SuppressFinalize(this);
134 /// Loads image from URL. Checks if image already loaded (cached).
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);
144 /// Loads image from URL. Checks if image already loaded (cached).
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
));
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
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
);
205 image
= LoadFromFile(imageFile
);
209 else if ( HttpContext
.Current
!= null )
211 image
= LoadFromFile(HttpContext
.Current
.Request
.MapPath(imageURL
));
216 // Try to load image from resource
222 // Check if resource class type was specified
223 int columnIndex
= imageURL
.IndexOf("::", StringComparison
.Ordinal
);
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(':');
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
));
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
274 catch (MissingManifestResourceException
)
280 // Try to load image using the Web Request
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
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
318 image
= LoadFromFile(imageURL
);
322 // Error loading image
325 #if ! Microsoft_CONTROL
326 throw(new ArgumentException( SR
.ExceptionImageLoaderIncorrectImageUrl( imageURL
) ) );
328 throw(new ArgumentException( SR
.ExceptionImageLoaderIncorrectImageLocation( imageURL
) ) );
332 // Save new image in cache
335 _imageData
[imageURL
] = image
;
342 /// Helper function which loads image from file.
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
)
360 /// Returns the image size taking the image DPI into consideration.
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
);
373 GetAdjustedImageSize(image
, graphics
, ref size
);
379 /// Returns the image size taking the image DPI into consideration.
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
;
394 size
.Width
= image
.Width
;
395 size
.Height
= image
.Height
;
400 /// Checks if the image has the same DPI as the graphics object.
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
)));