/// <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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }