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);
}
}
}
}