1

更新:我们用解决问题的替代方法(PDF 到图像)替换了图像生成,但我将保留这个问题,因为我想了解这是否可能。

在我们的网站http://www.cloudformatter.com上,我们试图实现一些代码来将我们生成的 XPS 文件处理为图像。除了页面中的 SVG 通过 VisualBrush 资源包含在 XPS 文档中之外,大多数都运行良好。

我们从这里的代码和网络 XPS周围的其他代码中获取灵感

下面是我们的转换器的代码,它正在为通过该网站的 REST 响应构建一个页面图像包。XPS 很好,大多数页面都按预期工作,因此代码目前适用于页面中除 SVG 之外的所有内容。我应该注意,生成用于下载的 XPS 的相同代码会生成输入到下面代码中的流,因此它不会被破坏。即使在调试中检查 Visual 也可以显示 VisualBrush 对象的存在。

这个页面是完美的(没有 SVG 图像)[单击“嵌入 PNG”和“下载 XPS”选项,它们是正确的。

http://www.cloudformatter.com/CSS2Pdf.APIDoc.Usage

但是这个页面有 SVG:

http://www.cloudformatter.com/CSS2Pdf.SVGCharts.HighCharts

下载 XPS 是完美的。但是使用以下代码获取 PNG 会导致 SVG 丢失。再次注意:后端实现的系统目前不使用下面的代码,因为我们找到了 PDF 到图像的工作解决方案。但是,我们想解决我们遇到的 XPS 到图像问题。XPS 有这个:

<Path>
            <Path.Fill>
                <VisualBrush Visual="{StaticResource svg0}" Viewbox="0,0,432.0,222.0"
                    Viewport="0,0,432.0,222.0" ViewportUnits="Absolute" ViewboxUnits="Absolute"
                />
            </Path.Fill>
            <Path.Data>
                <PathGeometry>
                    <PathFigure IsClosed="true" StartPoint="0,0">
                        <PolyLineSegment Points="0,0 432.0,0 432.0,222.0 0,222.0"/>
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>

资源有这个:

 ResourceDictionary xmlns="http://schemas.microsoft.com/xps/2005/06"
xmlns:x="http://schemas.microsoft.com/xps/2005/06/resourcedictionary-key">
<Canvas RenderTransform="1,0,0,1,0,0" x:Key="svg0">
    <Canvas RenderTransform="1.0,0.0,0.0,-1.0,0.0,222.0">
        <Canvas.Clip>
            <PathGeometry Figures="M 0.0,0.0 L 0.0,222.0 L 432.0,222.0 L 432.0,0.0 L 0.0,0.0 z "
            />
        </Canvas.Clip>
        <Path Fill="#ffffff" Data="M 0.0,0.0 L 0.0,222.0 L 432.0,222.0 L 432.0,0.0 L 0.0,0.0 z "/> 
 <!--snipped-->

代码如下。以这种方式获得页面的视觉效果是不可能的吗?

private static List<byte[]> XPStoIMG(Stream xpsStream)
    {
        xpsStream.Seek(0, SeekOrigin.Begin);

        List<byte[]> pages = new List<byte[]>();

        MemoryStream imgStream = new MemoryStream();
        var mt = new MultiThreader("single_thread", true);
        mt.Run(delegate()
        {
            using (Package package = Package.Open(xpsStream))
            {
                string inMemoryPackageName = "memorystream://myXps.xps";
                Uri packageUri = new Uri(inMemoryPackageName);
                PackageStore.AddPackage(packageUri, package);
                XpsDocument xpsDoc = new XpsDocument(package, CompressionOption.Maximum, inMemoryPackageName);

                FixedDocumentSequence seq = xpsDoc.GetFixedDocumentSequence();
                DocumentPaginator paginator = seq.DocumentPaginator;
                for (int page = 0; page < paginator.PageCount; page++)
                {
                    DocumentPage docPage = paginator.GetPage(page);
                    RenderTargetBitmap bmp = new RenderTargetBitmap((int)docPage.Size.Width * 120 / 96, (int)docPage.Size.Height * 120 / 96, 120d, 120d, PixelFormats.Default);
                    bmp.Render(docPage.Visual);
                    PngBitmapEncoder png = new PngBitmapEncoder();
                    png.Frames.Add(BitmapFrame.Create(bmp));
                    MemoryStream pstream = new MemoryStream();
                    png.Save(pstream);
                    pstream.Flush();
                    pstream.Seek(0, SeekOrigin.Begin);
                    byte[] parr = new byte[pstream.Length];
                    pstream.Read(parr, 0, Convert.ToInt32(pstream.Length));
                    pages.Add(parr);
                }
                PackageStore.RemovePackage(packageUri);
                xpsDoc.Close();
            }
        }, System.Threading.ApartmentState.STA);
        mt.Start();
        mt.CurrentThread.Join();
        return pages;
    }
4

1 回答 1

0

部分地。当你得到你的FixedDocumentSequence,你可以这样继续:

foreach (PageContent content in xps.GetFixedDocumentSequence().References.First().GetDocument(true).Pages) {
  FixedPage page = content.GetPageRoot(true);
  foreach (UIElement element in page.Children) {
    //... do what you want
  }
}

例如,您想要的部分可能是DrawingVisual为页面创建 a,RenderOpen()它获取 aDrawingContext并将单个elements 渲染到该上下文。完成后,您可以渲染整个收集的视觉效果RenderTargetBitmap

于 2016-08-24T14:17:05.097 回答