/// <summary> /// Gets the OpenXml ImagePartType associated to an image. /// </summary> public static ImagePartType?GetImagePartTypeForImageUrl(Uri uri) { String extension = Path.GetExtension(uri.IsAbsoluteUri ? uri.Segments[uri.Segments.Length - 1] : uri.OriginalString); if (knownExtensions.TryGetValue(extension, out ImagePartType type)) { return(type); } // extension not recognized, try with checking the query string. Expecting to resolve something like: // ./image.axd?picture=img1.jpg extension = System.IO.Path.GetExtension(uri.IsAbsoluteUri ? uri.AbsoluteUri : uri.ToString()); if (knownExtensions.TryGetValue(extension, out type)) { return(type); } // so, match text of the form: data:image/yyy;base64,zzzzzzzzzzzz... // where yyy is the MIME type, zzz is the base64 encoded data DataUri dataUri = DataUri.Parse(uri.ToString()); if (dataUri != null) { if (knownContentType.TryGetValue(dataUri.Mime, out type)) { return(type); } } return(null); }
//____________________________________________________________________ // // Public Functionality #region DownloadData /// <summary> /// Download the remote or local image located at the specified url. /// </summary> public HtmlImageInfo DownloadData(Uri imageUrl) { // is it a local path? if (imageUrl.IsFile) { // replace string %20 in LocalPath by daviderapicavoli (patch #15938) String localPath = Uri.UnescapeDataString(imageUrl.LocalPath); try { // just read the picture from the file system imageInfo.RawData = File.ReadAllBytes(localPath); } catch (Exception exc) { if (Logging.On) { Logging.PrintError("ImageDownloader.DownloadData(\"" + localPath + "\")", exc); } if (exc is IOException || exc is UnauthorizedAccessException || exc is System.Security.SecurityException || exc is NotSupportedException) { return(null); } throw; } return(imageInfo); } // data inline, encoded in base64 if (imageUrl.Scheme == "data") { DataUri dataUri = DataUri.Parse(imageUrl.OriginalString); return(DownloadData(dataUri)); } var response = BackChannels.CreateWebRequest(imageUrl); if (response != null) { imageInfo.RawData = response.Body; // For requested url with no filename, we need to read the media mime type if provided imageInfo.Type = InspectMimeType(response.ContentType); } return(imageInfo); }
/// <summary> /// Decrypt the given inline DataUri. /// </summary> public HtmlImageInfo DownloadData(DataUri dataUri) { if (dataUri == null) { return(null); } if (knownContentType.TryGetValue(dataUri.Mime, out ImagePartType type)) { imageInfo.Type = type; } imageInfo.RawData = dataUri.Data; return(imageInfo); }
private Drawing AddImagePart(String imageSource, String alt, Size preferredSize) { if (imageObjId == UInt32.MinValue) { // In order to add images in the document, we need to asisgn an unique id // to each Drawing object. So we'll loop through all of the existing <wp:docPr> elements // to find the largest Id, then increment it for each new image. drawingObjId = 1; // 1 is the minimum ID set by MS Office. imageObjId = 1; foreach (var d in mainPart.Document.Body.Descendants <Drawing>()) { if (d.Inline == null) { continue; // fix some rare issue where Inline is null (reported by scwebgroup) } if (d.Inline.DocProperties.Id > drawingObjId) { drawingObjId = d.Inline.DocProperties.Id; } var nvPr = d.Inline.Graphic.GraphicData.GetFirstChild <pic.NonVisualPictureProperties>(); if (nvPr != null && nvPr.NonVisualDrawingProperties.Id > imageObjId) { imageObjId = nvPr.NonVisualDrawingProperties.Id; } } if (drawingObjId > 1) { drawingObjId++; } if (imageObjId > 1) { imageObjId++; } } // Cache all the ImagePart processed to avoid downloading the same image. if (imagePrefetcher == null) { imagePrefetcher = new ImagePrefetcher(mainPart, webRequester); } HtmlImageInfo iinfo = imagePrefetcher.Download(imageSource); if (iinfo == null) { return(null); } if (preferredSize.IsEmpty) { preferredSize = iinfo.Size; } else if (preferredSize.Width <= 0 || preferredSize.Height <= 0) { Size actualSize = iinfo.Size; preferredSize = ImageHeader.KeepAspectRatio(actualSize, preferredSize); } long widthInEmus = new Unit(UnitMetric.Pixel, preferredSize.Width).ValueInEmus; long heightInEmus = new Unit(UnitMetric.Pixel, preferredSize.Height).ValueInEmus; ++drawingObjId; ++imageObjId; var img = new Drawing( new wp.Inline( new wp.Extent() { Cx = widthInEmus, Cy = heightInEmus }, new wp.EffectExtent() { LeftEdge = 19050L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, new wp.DocProperties() { Id = drawingObjId, Name = "Picture " + imageObjId, Description = String.Empty }, new wp.NonVisualGraphicFrameDrawingProperties { GraphicFrameLocks = new a.GraphicFrameLocks() { NoChangeAspect = true } }, new a.Graphic( new a.GraphicData( new pic.Picture( new pic.NonVisualPictureProperties { NonVisualDrawingProperties = new pic.NonVisualDrawingProperties() { Id = imageObjId, Name = DataUri.IsWellFormed(imageSource) ? string.Empty : imageSource, Description = alt }, NonVisualPictureDrawingProperties = new pic.NonVisualPictureDrawingProperties( new a.PictureLocks() { NoChangeAspect = true, NoChangeArrowheads = true }) }, new pic.BlipFill( new a.Blip() { Embed = iinfo.ImagePartId }, new a.SourceRectangle(), new a.Stretch( new a.FillRectangle())), new pic.ShapeProperties( new a.Transform2D( new a.Offset() { X = 0L, Y = 0L }, new a.Extents() { Cx = widthInEmus, Cy = heightInEmus }), new a.PresetGeometry( new a.AdjustValueList() ) { Preset = a.ShapeTypeValues.Rectangle } ) { BlackWhiteMode = a.BlackWhiteModeValues.Auto }) ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }) ) { DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U } ); return(img); }
private Drawing AddImagePart(Uri imageUrl, String imageSource, String alt, Size preferredSize) { if (imageObjId == UInt32.MinValue) { // In order to add images in the document, we need to asisgn an unique id // to each Drawing object. So we'll loop through all of the existing <wp:docPr> elements // to find the largest Id, then increment it for each new image. drawingObjId = 1; // 1 is the minimum ID set by MS Office. imageObjId = 1; foreach (var d in mainPart.Document.Body.Descendants <Drawing>()) { if (d.Inline == null) { continue; // fix some rare issue where Inline is null (reported by scwebgroup) } if (d.Inline.DocProperties.Id > drawingObjId) { drawingObjId = d.Inline.DocProperties.Id; } var nvPr = d.Inline.Graphic.GraphicData.GetFirstChild <pic.NonVisualPictureProperties>(); if (nvPr != null && nvPr.NonVisualDrawingProperties.Id > imageObjId) { imageObjId = nvPr.NonVisualDrawingProperties.Id; } } if (drawingObjId > 1) { drawingObjId++; } if (imageObjId > 1) { imageObjId++; } } // Cache all the ImagePart processed to avoid downloading the same image. CachedImagePart imagePart = null; // if imageUrl is null, we may consider imageSource is a DataUri. // thus, no need to download and cache anything if (imageUrl == null || !knownImageParts.TryGetValue(imageUrl, out imagePart)) { HtmlImageInfo iinfo = null; ImageProvisioningProvider provider = new ImageProvisioningProvider(this.WebProxy, preferredSize); if (imageUrl == null) { iinfo = provider.DownloadData(DataUri.Parse(imageSource)); } else if (this.ImageProcessing == ImageProcessing.ManualProvisioning) { // as HtmlImageInfo is a class, the EventArgs will act as a proxy iinfo = new HtmlImageInfo() { Size = preferredSize }; ProvisionImageEventArgs args = new ProvisionImageEventArgs(imageUrl, iinfo); OnProvisionImage(args); // did the user want to ignore this image? if (args.Cancel) { return(null); } } // Automatic Processing or the user did not supply himself the image and did not cancel the provisioning. // We download ourself the image. if (iinfo == null || (iinfo.RawData == null && imageUrl.IsAbsoluteUri)) { iinfo = provider.DownloadData(imageUrl); } if (!ImageProvisioningProvider.Provision(iinfo, imageUrl)) { return(null); } ImagePart ipart = mainPart.AddImagePart(iinfo.Type.Value); imagePart = new CachedImagePart() { Part = ipart }; imagePart.Width = iinfo.Size.Width; imagePart.Height = iinfo.Size.Height; using (Stream outputStream = ipart.GetStream(FileMode.Create)) { outputStream.Write(iinfo.RawData, 0, iinfo.RawData.Length); outputStream.Seek(0L, SeekOrigin.Begin); } if (imageUrl != null) // don't need to cache inlined-image { knownImageParts.Add(imageUrl, imagePart); } } if (preferredSize.IsEmpty) { preferredSize.Width = imagePart.Width; preferredSize.Height = imagePart.Height; } else if (preferredSize.Width <= 0 || preferredSize.Height <= 0) { Size actualSize = new Size(imagePart.Width, imagePart.Height); preferredSize = ImageHeader.KeepAspectRatio(actualSize, preferredSize); } String imagePartId = mainPart.GetIdOfPart(imagePart.Part); long widthInEmus = new Unit(UnitMetric.Pixel, preferredSize.Width).ValueInEmus; long heightInEmus = new Unit(UnitMetric.Pixel, preferredSize.Height).ValueInEmus; ++drawingObjId; ++imageObjId; var img = new Drawing( new wp.Inline( new wp.Extent() { Cx = widthInEmus, Cy = heightInEmus }, new wp.EffectExtent() { LeftEdge = 19050L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, new wp.DocProperties() { Id = drawingObjId, Name = imageSource, Description = String.Empty }, new wp.NonVisualGraphicFrameDrawingProperties { GraphicFrameLocks = new a.GraphicFrameLocks() { NoChangeAspect = true } }, new a.Graphic( new a.GraphicData( new pic.Picture( new pic.NonVisualPictureProperties { NonVisualDrawingProperties = new pic.NonVisualDrawingProperties() { Id = imageObjId, Name = imageSource, Description = alt }, NonVisualPictureDrawingProperties = new pic.NonVisualPictureDrawingProperties( new a.PictureLocks() { NoChangeAspect = true, NoChangeArrowheads = true }) }, new pic.BlipFill( new a.Blip() { Embed = imagePartId }, new a.SourceRectangle(), new a.Stretch( new a.FillRectangle())), new pic.ShapeProperties( new a.Transform2D( new a.Offset() { X = 0L, Y = 0L }, new a.Extents() { Cx = widthInEmus, Cy = heightInEmus }), new a.PresetGeometry( new a.AdjustValueList() ) { Preset = a.ShapeTypeValues.Rectangle } ) { BlackWhiteMode = a.BlackWhiteModeValues.Auto }) ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }) ) { DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U } ); return(img); }