问题
I have a V:Shape
that I am assuming has come from the conversion of a .Doc file to a .Docx file, but in the code I have written, I am wanting a DocumentFormat.OpenXml.Drawing.Pictures.Picture
.
Is there any way to programically convert to a Picture
?
The snippet I'm using is:
foreach (var item in value)
{
if (!item.Descendants<Picture>().Any()) //pictures are processed differently - they're an absolute s**t storm to code...
{
p.Append(item.CloneNode(true));
}
else
{
p.Append(CreateImageRun(source, item, target, f));
}
}
public Run CreateImageRun(WordprocessingDocument sourceDoc, Run sourceRun, WordprocessingDocument target, FooterPart footerPart)
{
ImagePart newPart = footerPart.AddImagePart(ImagePartType.Png);
ImageData shape = sourceRun.Descendants<ImageData>().FirstOrDefault();
ImagePart p = sourceDoc.MainDocumentPart.GetPartById(shape.RelationshipId) as ImagePart;
Bitmap image = new Bitmap(p.GetStream());
using (Stream s = p.GetStream())
{
s.Position = 0;
newPart.FeedData(s);
}
string partId = footerPart.GetIdOfPart(newPart);
Drawing newImage = CreateImage(partId);
return new Run(newImage);
}
private Drawing CreateImage(string relationshipId)
{
// Define the reference of the image.
return new Drawing(
new DW.Inline(
new DW.Extent() { Cx = 990000L, Cy = 792000L },
new DW.EffectExtent()
{
LeftEdge = 0L,
TopEdge = 0L,
RightEdge = 0L,
BottomEdge = 0L
},
new DW.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Picture 1"
},
new DW.NonVisualGraphicFrameDrawingProperties(
new A.GraphicFrameLocks() { NoChangeAspect = true }),
new A.Graphic(
new A.GraphicData(
new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties()
{
Id = (UInt32Value)0U,
Name = "New Bitmap Image.jpg"
},
new PIC.NonVisualPictureDrawingProperties()),
new PIC.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri =
"{28A0092B-C50C-407E-A947-70E740481C1C}"
})
)
{
Embed = relationshipId,
CompressionState =
A.BlipCompressionValues.Print
},
new A.Stretch(
new A.FillRectangle())),
new PIC.ShapeProperties(
new A.Transform2D(
new A.Offset() { X = 0L, Y = 0L },
new A.Extents() { Cx = 990000L, Cy = 792000L }),
new A.PresetGeometry(
new A.AdjustValueList()
) { Preset = A.ShapeTypeValues.Rectangle }))
) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
)
{
DistanceFromTop = (UInt32Value)0U,
DistanceFromBottom = (UInt32Value)0U,
DistanceFromLeft = (UInt32Value)0U,
DistanceFromRight = (UInt32Value)0U,
EditId = "50D07946"
});
}
Full code context is in a different question here:
Creating an ImagePart isn't saving the Relationship in OpenXML
回答1:
I found a quick/simple way to do this - and I should have worked it out earlier!
The Shape
object has a ImageData
object as a descendant, so I checked for that, and ran it through an extra method to get the ImagePart
:
A.Blip pic = item.Descendants<A.Blip>().FirstOrDefault();
ImageData imageData = item.Descendants<ImageData>().FirstOrDefault();
if (pic == null && imageData == null) //pictures are processed differently - they're an absolute s**t storm to code...
{
runToAmend.InsertAfterSelf(item.CloneNode(true));
}
else
{
if(pic != null)
{
runToAmend.InsertAfterSelf(CreateImageFromBlip(source, item, footerHeaderPart,pic));
}
else if (imageData != null)
{
runToAmend.InsertAfterSelf(CreateImageFromShape(source, item, footerHeaderPart, imageData));
}
}
Then created a new method - CreateImageFromShape(..)
which then calls the original CreateImageRun.
private Run CreateImageFromShape(WordprocessingDocument sourceDoc, Run sourceRun, OpenXmlPart headerFooterPart, ImageData imageData)
{
ImagePart p = sourceDoc.MainDocumentPart.GetPartById(imageData.RelationshipId) as ImagePart;
return CreateImageRun(sourceDoc, sourceRun, headerFooterPart, p);
}
Job done.
来源:https://stackoverflow.com/questions/19712900/converting-a-vshape-embed-to-a-wdrawing