/// <summary> /// Gets the base64 encoded string for the given icon resource url. This method has the potential to be very slow /// as it will create a new resourceManager for a given assembly and search that assembly, which may require disk access. /// </summary> /// <param name="icon">Icon Url</param> /// <param name="extension">Returns the extension to describe the type of resource.</param> /// <returns>a base64 encoded string version of an image if found else null.</returns> private string GetIconAsBase64(IconUrl icon, out string extension) { extension = "png"; var path = Path.GetFullPath(icon.Path); //Get full path if it's a relative path. var libraryCustomization = getForAssemblyMethodInfo.Invoke(null, new object[] { path, pathManager, true }); if (libraryCustomization == null) { return(null); } var assembly = LibraryCustomizationResourceAssemblyProperty.GetValue(libraryCustomization) as Assembly; if (assembly == null) { return(null); } // "Name" can be "Some.Assembly.Name.customization" with multiple dots, // we are interested in removal of the "customization" part and the middle dots. var temp = assembly.GetName().Name.Split('.'); var assemblyName = String.Join("", temp.Take(temp.Length - 1)); var rm = new ResourceManager(assemblyName + imagesSuffix, assembly); using (var image = (Bitmap)rm.GetObject(icon.Name)) { if (image == null) { return(null); } var tempstream = new MemoryStream(); image.Save(tempstream, image.RawFormat); byte[] imageBytes = tempstream.ToArray(); tempstream.Dispose(); string base64String = Convert.ToBase64String(imageBytes); return(base64String); } }
/// <summary> /// Retrieves the resource for a given url as a base64 encoded string. /// ie data:image/png;base64, stringxxxyyyzzz /// </summary> /// <param name="url">url for the requested icon</param> /// <param name="extension">Returns the extension to describe the type of resource.</param> /// <returns></returns> public string GetResourceAsString(string url, out string extension) { //sometimes the urls have "about:" added to them - remove this //and do it before checking cache. //https://en.wikipedia.org/wiki/About_URI_scheme if (url.StartsWith("about:")) { url = url?.Replace("about:", string.Empty); } if (!String.IsNullOrEmpty(url) && urlToBase64DataCache.ContainsKey(url)) { var cachedData = urlToBase64DataCache[url]; extension = cachedData.Item2; return(cachedData.Item1); } //because we modify the spec the icon urls may have been replaced by base64 encoded images //if thats the case, no need to look them up again from disk, just return the string. if (!String.IsNullOrEmpty(url) && url.Contains("data:image/")) { var match = Regex.Match(url, @"data:(?<type>.+?);base64,(?<data>.+)"); var base64Data = match.Groups["data"].Value; var contentType = match.Groups["type"].Value; //image/png -> png extension = contentType.Split('/').Skip(1).FirstOrDefault(); urlToBase64DataCache.Add(url, Tuple.Create(base64Data, extension)); return(base64Data); } var base64String = string.Empty; extension = "png"; //Create IconUrl to parse the request.Url to icon name and path. if (String.IsNullOrEmpty(url)) { return(string.Empty); } //before trying to create a uri we have to handle resources that might //be embedded into the resources.dlls //these paths will start with ./dist if (url.StartsWith(@"./dist")) { //make relative url a full uri var urlAbs = url.Replace(@"./dist", @"http://localhost/dist"); var ext = string.Empty; var stream = embeddedDllResourceProvider.GetResource(urlAbs, out ext); if (stream != null) { extension = ext; base64String = GetIconAsBase64(stream, ext); } } else { //TODO check if absolute instead of using try/catch try { var icon = new IconUrl(new Uri(url)); base64String = GetIconAsBase64(icon, out extension); } catch (Exception) { //look in resources for registered path and just use the stream directly var resourceDict = this.customization.Resources.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); if (resourceDict.ContainsKey(url)) { var fileExtension = System.IO.Path.GetExtension(url); extension = fileExtension; base64String = GetIconAsBase64(resourceDict[url], fileExtension); } } } if (base64String == null) { base64String = GetDefaultIconBase64(out extension); } urlToBase64DataCache.Add(url, Tuple.Create(base64String, extension)); return(base64String); }