Exemplo n.º 1
0
        protected PackagePart clonePackagePart(PackagePart pp)
        {
            PackagePart new_pp = package.CreatePart(pp.Uri, pp.ContentType, CompressionOption.Normal);

            using (Stream s_read = pp.GetStream())
            {
                using (Stream s_write = new PackagePartStream(new_pp.GetStream(FileMode.Create)))
                {
                    byte[] buffer = new byte[32768];
                    int read;
                    while ((read = s_read.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        s_write.Write(buffer, 0, read);
                    }
                }
            }

            return new_pp;
        }
Exemplo n.º 2
0
        private void merge_images(PackagePart remote_pp, DocX remote_document, XDocument remote_mainDoc, String contentType)
        {
            // Before doing any other work, check to see if this image is actually referenced in the document.
            // In my testing I have found cases of Images inside documents that are not referenced
            var remote_rel = remote_document.mainPart.GetRelationships().Where(r => r.TargetUri.OriginalString.Equals(remote_pp.Uri.OriginalString.Replace("/word/", ""))).FirstOrDefault();
            if (remote_rel == null) {
                remote_rel = remote_document.mainPart.GetRelationships().Where(r => r.TargetUri.OriginalString.Equals(remote_pp.Uri.OriginalString)).FirstOrDefault();
                if (remote_rel == null)
                    return;
            }
            String remote_Id = remote_rel.Id;

            String remote_hash = ComputeMD5HashString(remote_pp.GetStream());
            var image_parts = package.GetParts().Where(pp => pp.ContentType.Equals(contentType));

            bool found = false;
            foreach (var part in image_parts)
            {
                String local_hash = ComputeMD5HashString(part.GetStream());
                if (local_hash.Equals(remote_hash))
                {
                    // This image already exists in this document.
                    found = true;

                    var local_rel = mainPart.GetRelationships().Where(r => r.TargetUri.OriginalString.Equals(part.Uri.OriginalString.Replace("/word/", ""))).FirstOrDefault();
                    if (local_rel == null)
                    {
                        local_rel = mainPart.GetRelationships().Where(r => r.TargetUri.OriginalString.Equals(part.Uri.OriginalString)).FirstOrDefault();
                    }
                    if (local_rel != null)
                    {
                        String new_Id = local_rel.Id;

                        // Replace all instances of remote_Id in the local document with local_Id
                        var elems = remote_mainDoc.Descendants(XName.Get("blip", a.NamespaceName));
                        foreach (var elem in elems)
                        {
                            XAttribute embed = elem.Attribute(XName.Get("embed", r.NamespaceName));
                            if (embed != null && embed.Value == remote_Id)
                            {
                                embed.SetValue(new_Id);
                            }
                        }

                        // Replace all instances of remote_Id in the local document with local_Id (for shapes as well)
                        var v_elems = remote_mainDoc.Descendants(XName.Get("imagedata", v.NamespaceName));
                        foreach (var elem in v_elems)
                        {
                            XAttribute id = elem.Attribute(XName.Get("id", r.NamespaceName));
                            if (id != null && id.Value == remote_Id)
                            {
                                id.SetValue(new_Id);
                            }
                        }
                    }

                    break;
                }
            }

            // This image does not exist in this document.
            if (!found)
            {
                String new_uri = remote_pp.Uri.OriginalString;
                new_uri = new_uri.Remove(new_uri.LastIndexOf("/"));
                //new_uri = new_uri.Replace("word/", "");
                new_uri += "/" + Guid.NewGuid() + contentType.Replace("image/", ".");
                if (!new_uri.StartsWith("/"))
                    new_uri = "/" + new_uri;

                PackagePart new_pp = package.CreatePart(new Uri(new_uri, UriKind.Relative), remote_pp.ContentType, CompressionOption.Normal);

                using (Stream s_read = remote_pp.GetStream())
                {
                    using (Stream s_write = new PackagePartStream(new_pp.GetStream(FileMode.Create)))
                    {
                        byte[] buffer = new byte[32768];
                        int read;
                        while ((read = s_read.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            s_write.Write(buffer, 0, read);
                        }
                    }
                }

                PackageRelationship pr = mainPart.CreateRelationship(new Uri(new_uri, UriKind.Relative), TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");

                String new_Id = pr.Id;

                //Check if the remote relationship id is a default rId from Word
                Match defRelId = Regex.Match(remote_Id, @"rId\d+", RegexOptions.IgnoreCase);

                // Replace all instances of remote_Id in the local document with local_Id
                var elems = remote_mainDoc.Descendants(XName.Get("blip", a.NamespaceName));
                foreach (var elem in elems)
                {
                    XAttribute embed = elem.Attribute(XName.Get("embed", r.NamespaceName));
                    if (embed != null && embed.Value == remote_Id)
                    {
                        embed.SetValue(new_Id);
                    }
                }

                if (!defRelId.Success)
                {
                    // Replace all instances of remote_Id in the local document with local_Id
                    var elems_local = mainDoc.Descendants(XName.Get("blip", a.NamespaceName));
                    foreach (var elem in elems_local)
                    {
                        XAttribute embed = elem.Attribute(XName.Get("embed", r.NamespaceName));
                        if (embed != null && embed.Value == remote_Id)
                        {
                            embed.SetValue(new_Id);
                        }
                    }

                    // Replace all instances of remote_Id in the local document with local_Id
                    var v_elems_local = mainDoc.Descendants(XName.Get("imagedata", v.NamespaceName));
                    foreach (var elem in v_elems_local)
                    {
                        XAttribute id = elem.Attribute(XName.Get("id", r.NamespaceName));
                        if (id != null && id.Value == remote_Id)
                        {
                            id.SetValue(new_Id);
                        }
                    }
                }

                // Replace all instances of remote_Id in the local document with local_Id (for shapes as well)
                var v_elems = remote_mainDoc.Descendants(XName.Get("imagedata", v.NamespaceName));
                foreach (var elem in v_elems)
                {
                    XAttribute id = elem.Attribute(XName.Get("id", r.NamespaceName));
                    if (id != null && id.Value == remote_Id)
                    {
                        id.SetValue(new_Id);
                    }
                }
            }
        }
Exemplo n.º 3
0
        internal Image AddImage(object o, string contentType = "image/jpeg")
        {
            // Open a Stream to the new image being added.
            Stream newImageStream;
            if (o is string)
                newImageStream = new FileStream(o as string, FileMode.Open, FileAccess.Read);
            else
                newImageStream = o as Stream;

            // Get all image parts in word\document.xml

            PackageRelationshipCollection relationshipsByImages = mainPart.GetRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
            List<PackagePart> imageParts = relationshipsByImages.Select(ir => package.GetParts().FirstOrDefault(p => p.Uri.ToString().EndsWith(ir.TargetUri.ToString()))).Where(e => e != null).ToList();

            foreach (PackagePart relsPart in package.GetParts().Where(part => part.Uri.ToString().Contains("/word/")).Where(part => part.ContentType.Equals("application/vnd.openxmlformats-package.relationships+xml")))
            {
                XDocument relsPartContent;
                using (TextReader tr = new StreamReader(relsPart.GetStream(FileMode.Open, FileAccess.Read)))
                    relsPartContent = XDocument.Load(tr);

                IEnumerable<XElement> imageRelationships =
                relsPartContent.Root.Elements().Where
                (
                    imageRel =>
                    imageRel.Attribute(XName.Get("Type")).Value.Equals("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image")
                );

                foreach (XElement imageRelationship in imageRelationships)
                {
                    if (imageRelationship.Attribute(XName.Get("Target")) != null)
                    {
                        string targetMode = string.Empty;

                        XAttribute targetModeAttibute = imageRelationship.Attribute(XName.Get("TargetMode"));
                        if (targetModeAttibute != null)
                        {
                            targetMode = targetModeAttibute.Value;
                        }

                        if (!targetMode.Equals("External"))
                        {
                            string imagePartUri = Path.Combine(Path.GetDirectoryName(relsPart.Uri.ToString()), imageRelationship.Attribute(XName.Get("Target")).Value);
                            imagePartUri = Path.GetFullPath(imagePartUri.Replace("\\_rels", string.Empty));
                            imagePartUri = imagePartUri.Replace(Path.GetFullPath("\\"), string.Empty).Replace("\\", "/");

                            if (!imagePartUri.StartsWith("/"))
                                imagePartUri = "/" + imagePartUri;

                            PackagePart imagePart = package.GetPart(new Uri(imagePartUri, UriKind.Relative));
                            imageParts.Add(imagePart);
                        }
                    }
                }
            }

            // Loop through each image part in this document.
            foreach (PackagePart pp in imageParts)
            {
                // Open a tempory Stream to this image part.
                using (Stream tempStream = pp.GetStream(FileMode.Open, FileAccess.Read))
                {
                    // Compare this image to the new image being added.
                    if (HelperFunctions.IsSameFile(tempStream, newImageStream))
                    {
                        // Get the image object for this image part
                        string id = mainPart.GetRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image")
                        .Where(r => r.TargetUri == pp.Uri)
                        .Select(r => r.Id).First();

                        // Return the Image object
                        return Images.Where(i => i.Id == id).First();
                    }
                }
            }

            string imgPartUriPath = string.Empty;
            string extension = contentType.Substring(contentType.LastIndexOf("/") + 1);
            do
            {
                // Create a new image part.
                imgPartUriPath = string.Format
                (
                    "/word/media/{0}.{1}",
                    Guid.NewGuid(), // The unique part.
                    extension
                );

            } while (package.PartExists(new Uri(imgPartUriPath, UriKind.Relative)));

            // We are now guareenteed that imgPartUriPath is unique.
            PackagePart img = package.CreatePart(new Uri(imgPartUriPath, UriKind.Relative), contentType, CompressionOption.Normal);

            // Create a new image relationship
            PackageRelationship rel = mainPart.CreateRelationship(img.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");

            // Open a Stream to the newly created Image part.
            using (Stream stream = new PackagePartStream(img.GetStream(FileMode.Create, FileAccess.Write)))
            {
                // Using the Stream to the real image, copy this streams data into the newly create Image part.
                using (newImageStream)
                {
                    byte[] bytes = new byte[newImageStream.Length];
                    newImageStream.Read(bytes, 0, (int)newImageStream.Length);
                    stream.Write(bytes, 0, (int)newImageStream.Length);
                }// Close the Stream to the new image.
            }// Close the Stream to the new image part.

            return new Image(this, rel);
        }