2015-07-29 4 views
1

MISE À JOUR: Nous avons remplacé la génération d'image avec une alternative qui résout le problème (PDF à l'image), mais je vais laisser cette question ouverte comme je voudrais comprendre si cela est possible.VisualBrush Ressources non incluses dans Visual en XPS à la conversion bitmap

Sur notre site Web au http://www.cloudformatter.com, nous essayions d'implémenter du code pour traiter les fichiers XPS générés à l'image. La plupart fonctionnent bien, sauf pour les fichiers SVG de la page qui sont inclus dans le document XPS via les ressources VisualBrush.

Nous avons pris inspriation du code ici et quelques autres sur le web XPS to image

Ci-dessous le code pour notre convertisseur qui construit un ensemble d'images de page pour une réponse REST à travers ce site. Le XPS est très bien et la plupart des pages fonctionnent comme prévu pour l'image, donc le code fonctionne actuellement pour tout sauf SVG dans les pages. Je devrais noter que le même code que le XPS génère pour le téléchargement génère le flux introduit dans le code ci-dessous afin qu'il ne soit pas cassé. Même en examinant Visual dans le débogage montre l'existence des objets VisualBrush.

Cette page est parfaite (pas d'images SVG) [cliquez sur "embed PNG" et "download XPS" options et ils sont corrects.

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

Mais cette page a SVG:

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

Le téléchargement XPS est parfait. Mais obtenir le PNG avec le code ci-dessous entraîne la perte des SVG. Notez encore: Le système implémenté sur le backend n'utilise pas le code ci-dessous car nous avons trouvé une solution de travail pour l'image PDF. Cependant, nous aimerions résoudre le problème XPS à l'image que nous avons. Le XPS a ceci:

<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> 

Et la ressource a ceci:

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--> 

Le code est ci-dessous. Est-ce que ce n'est pas possible d'obtenir le visuel de la page de cette façon?

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; 
    } 
+1

tl; dr mais supposez-vous que Path.Data == SVG? Parce que les formats sont similaires, mais différents. Je ne suis pas à 100% sur les détails, mais je suis à peu près sûr que les deux formats ne sont pas (toujours) directement compatibles les uns avec les autres. – Will

+1

Non. Les données de chemin proviennent du svg et sont correctement placées dans le XPS. Vous pouvez voir que si vous choisissez de télécharger en tant que XPS. C'est bon. Ce que j'essayais de faire est de convertir ce XPS en image. –

Répondre

0

En partie. Lorsque vous avez obtenu votre FixedDocumentSequence, vous pouvez continuer comme ça:

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

Le ce que vous voulez partie pourrait être, par exemple, pour créer un DrawingVisual pour la page, RenderOpen() pour obtenir un DrawingContext et de rendre la individuels element s dans ce contexte. Lorsque vous avez terminé, vous pouvez rendre tout le visuel collecté à un RenderTargetBitmap tout droit.