在 WordprocessingML 中嵌入图像时获取原始图像尺寸

发布于 2024-07-13 17:48:38 字数 1177 浏览 14 评论 0原文

我正在使用 Velocity 模板引擎动态创建 Word 文档。 这些文档以 XML 格式创建(使用 Microsoft Office 2003 WordprocessML XML 标准)。

我以传统方式将图像(以 Base64 格式编码)嵌入到 WordML 中:

<w:pict>  
    <v:shapeType> ... </v:shapeType>    
    <w:binData w:name="wordml://02000002.jpg"> [ encoded data] </w:binData>

    <v:shape id="_x0000_s1026"  
           type="#_x0000_t75"
           style="width:100%;height:100%" 
           o:allowoverlap="f"
           >
        <v:imagedata src="wordml://02000002.jpg" o:title="testimage2">
        </v:imagedata>
    </v:shape>

</w:pict>

问题在于图像大小调整/缩放。 请注意 标记上的 style 属性。 将高度和宽度设置为 100% 不会将图像调整为实际大小。 它将高度和宽度设置为大约 1.04 英寸,这会导致图像倾斜。 忽略高度和宽度具有相同的效果。 将高度和宽度设置为 auto 具有相同的效果。

最烦人的是,如果我在 Word 2003 中打开生成的文档,右键单击图像,打开“设置图片格式”对话框,然后转到“大小”选项卡,它会在“原始大小”下显示正确的高度和宽度。 它甚至提供了一个“重置”按钮,可将图像大小调整为原始大小(假设选中“相对于原始图片大小”复选框。)

我喜欢:!*@&#^#% ???

所以我的问题是:

在 WordML 的上下文中是否可以获取图像的原始大小值(或指示 Word 使用原始图像大小) ?

如果有人可以帮助解决这个问题,我保证我会写一篇深入的博客文章,以确保我将是最后一个必须处理这个问题的人。

I am dynamically creating Word documents using the Velocity template engine. The documents are created in XML (using the Microsoft Office 2003 WordprocessML XML standard).

I am embedding an image (encoded in Base64 format) inside the WordML in the traditional way:

<w:pict>  
    <v:shapeType> ... </v:shapeType>    
    <w:binData w:name="wordml://02000002.jpg"> [ encoded data] </w:binData>

    <v:shape id="_x0000_s1026"  
           type="#_x0000_t75"
           style="width:100%;height:100%" 
           o:allowoverlap="f"
           >
        <v:imagedata src="wordml://02000002.jpg" o:title="testimage2">
        </v:imagedata>
    </v:shape>

</w:pict>

The issue is with image sizing / scaling. Note the style attribute on the <v:shape> tag. Setting height and width to 100% does not size the image to its actual size. It sets height and width to approximately 1.04 inches which skews the image. Leaving off the height and width has the same effect. Setting height and width to auto has the same effect.

Most annoyingly, if I open the generated document in Word 2003, right click on the image, open the Format Picture dialog, and go to the Size tab it display the correct height and width under "Original size." It even provides a "Reset" button that resizes the image to its original size (assuming the "Relative to original picture size" checkbox is checked.)

I am like: !*@&#^#% ???

So my question is:

Is there anyway in the context of WordML to get the original size values for the image (or instruct Word to use the original image size)?

If someone can help will this question, I promise I will write an in depth blog post to ensure that I will be the last person that has to deal with this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

宛菡 2024-07-20 17:48:39

如果您使用 xslt 模板,您可以在模板中编写一些 C# 脚本,如下所示(它用于图元文件(.wmf),但您可以为 Bitmap 类重写它以与 .jpg 格式一起使用):

<msxsl:script language="C#" implements-prefix="user">
     <msxsl:assembly name="System.Drawing" />
    <msxsl:using namespace="System.Drawing.Imaging" />


     <![CDATA[

          public static double getImageWidthFrom64String(string base64)
            {
            byte[] bytes = Convert.FromBase64String(file);
            System.Drawing.Imaging.Metafile image;
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes))
            {
                image =
(System.Drawing.Imaging.Metafile)System.Drawing.Imaging.Metafile.FromStream(ms);
            }
       return image.Width;
            }

             public static double getImageHeightFrom64String(string base64)
            {
            byte[] bytes = Convert.FromBase64String(file);
            System.Drawing.Imaging.Metafile image;
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes))
            {
                image =
(System.Drawing.Imaging.Metafile)System.Drawing.Imaging.Metafile.FromStream(ms);
            }      
            return image.Height;
            }
     ]]>
      </msxsl:script>

然后您可以使用这些函数来获得真正的效果模板中的图像尺寸:

<xsl:template match="/ns1:Work/ns1:leaderSignature">
    <ns1:picture>
      <xsl:for-each select="@ns1:*|@*[namespace-uri()='']">
        <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
          <xsl:value-of select="." />
        </xsl:attribute>
      </xsl:for-each>
      <xsl:variable name="filename" select="concat(concat('leadsig',ancestor::ns1:Work/ns1:id),'.wmz')"/>
      <xsl:variable name="file64String" select="."></xsl:variable> 
      <w:r>
        <w:rPr>
          <w:noProof />
        </w:rPr>
        <w:pict>    
          <w:binData w:name="{concat('wordml:\\',$filename)}">
            <xsl:value-of select="." />
          </w:binData>
          <v:shape id="pic3" o:spid="_x0000_s1028"  style="
            width:{user:getImageWidthFrom64String($file64String)};
            height:{user:getImageHeightFrom64String($file64String)};
            position:absolute;         
            text-align:left;
            left:0;
            margin-left:430pt;
            margin-top:192pt;       
            z-index:2;   
            visibility:visible;
            mso-position-horizontal-relative:page;
            mso-position-horizontal:absolute;
            mso-position-vertical-relative:page;
            mso-position-vertical:absolute;   
            mso-wrap-style:square;
            mso-wrap-distance-left:9pt;
            mso-wrap-distance-top:0;
            mso-wrap-distance-right:9pt;
            mso-wrap-distance-bottom:0">         
            <v:imagedata src="{concat('wordml:\\',$filename)}" o:title="" />
           <w10:wrap anchorx="page" anchory="page" />
          </v:shape>
        </w:pict>  
      </w:r>
    </ns1:picture>
  </xsl:template><!--Leader Signature-->

If you are using xslt templates you can write some C# script in your template like that(it's for metafiles(.wmf) but you can rewrite it for Bitmap class to use with .jpg format):

<msxsl:script language="C#" implements-prefix="user">
     <msxsl:assembly name="System.Drawing" />
    <msxsl:using namespace="System.Drawing.Imaging" />


     <![CDATA[

          public static double getImageWidthFrom64String(string base64)
            {
            byte[] bytes = Convert.FromBase64String(file);
            System.Drawing.Imaging.Metafile image;
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes))
            {
                image =
(System.Drawing.Imaging.Metafile)System.Drawing.Imaging.Metafile.FromStream(ms);
            }
       return image.Width;
            }

             public static double getImageHeightFrom64String(string base64)
            {
            byte[] bytes = Convert.FromBase64String(file);
            System.Drawing.Imaging.Metafile image;
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes))
            {
                image =
(System.Drawing.Imaging.Metafile)System.Drawing.Imaging.Metafile.FromStream(ms);
            }      
            return image.Height;
            }
     ]]>
      </msxsl:script>

Then you can use these functions to get real image size in your template:

<xsl:template match="/ns1:Work/ns1:leaderSignature">
    <ns1:picture>
      <xsl:for-each select="@ns1:*|@*[namespace-uri()='']">
        <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
          <xsl:value-of select="." />
        </xsl:attribute>
      </xsl:for-each>
      <xsl:variable name="filename" select="concat(concat('leadsig',ancestor::ns1:Work/ns1:id),'.wmz')"/>
      <xsl:variable name="file64String" select="."></xsl:variable> 
      <w:r>
        <w:rPr>
          <w:noProof />
        </w:rPr>
        <w:pict>    
          <w:binData w:name="{concat('wordml:\\',$filename)}">
            <xsl:value-of select="." />
          </w:binData>
          <v:shape id="pic3" o:spid="_x0000_s1028"  style="
            width:{user:getImageWidthFrom64String($file64String)};
            height:{user:getImageHeightFrom64String($file64String)};
            position:absolute;         
            text-align:left;
            left:0;
            margin-left:430pt;
            margin-top:192pt;       
            z-index:2;   
            visibility:visible;
            mso-position-horizontal-relative:page;
            mso-position-horizontal:absolute;
            mso-position-vertical-relative:page;
            mso-position-vertical:absolute;   
            mso-wrap-style:square;
            mso-wrap-distance-left:9pt;
            mso-wrap-distance-top:0;
            mso-wrap-distance-right:9pt;
            mso-wrap-distance-bottom:0">         
            <v:imagedata src="{concat('wordml:\\',$filename)}" o:title="" />
           <w10:wrap anchorx="page" anchory="page" />
          </v:shape>
        </w:pict>  
      </w:r>
    </ns1:picture>
  </xsl:template><!--Leader Signature-->
花开柳相依 2024-07-20 17:48:39

您需要将“v:shape”元素的“style”属性中的宽度和高度设置为0px。 例如:

<v:shape style="width:0px;height:0px" >

图像将具有原始大小。

You need to set width and height in "style" attribute of "v:shape" element to 0px. For example:

<v:shape style="width:0px;height:0px" >

And image will have original size.

┼── 2024-07-20 17:48:39

我不明白为什么要依赖 WordML 来获取图像大小? 您正在将图像输入到Word文档中,您可以使用Bitmap类获取图像大小。

I don't understand why are you relying on WordML to get the image size? You are feeding an image into word document, you can get image size by using Bitmap class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文