2015-07-29 3 views
1

ОБНОВЛЕНИЕ: Мы заменили генерацию изображения альтернативой, которая решает проблему (в формате PDF для изображения), но я собираюсь оставить этот вопрос открытым, поскольку я хотел бы понять, возможно.Ресурсы VisualBrush, не включенные в визуальное преобразование XPS в растровое изображение

На нашем сайте в http://www.cloudformatter.com мы пытались реализовать некоторый код для обработки наших сгенерированных файлов XPS для изображения. Большинство из них хорошо работает, за исключением SVG на странице, которые включены в документ XPS через ресурсы VisualBrush.

Мы взяли inspriation из кода здесь и некоторых других вокруг сети XPS to image

Ниже код нашего преобразователя, который строит пакет изображений страниц для ответа REST через этот сайт. XPS хорош, и большинство страниц работают как ожидалось для изображения, поэтому код работает в настоящее время для всего, кроме SVG на страницах. Я должен отметить, что тот же код, который генерирует XPS для загрузки, генерирует поток, переданный в код ниже, поэтому он не прерывается. Даже проверка Visual в debug показывает существование объектов 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; 
    } 
+1

tl; dr, но вы предполагаете, что Path.Data == SVG? Потому что форматы похожи, но разные. Я не на 100% на детали, но я уверен, что два формата не всегда (всегда) напрямую совместимы друг с другом. – Will

+1

№. Данные пути поступают из svg и правильно помещаются в XPS. Вы можете видеть, что если вы решите скачать как XPS. Это нормально. То, что я пытался сделать, - это преобразовать этот XPS в изображение. –

ответ

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 для страницы, RenderOpen() это, чтобы получить DrawingContext и отдавая индивидуальный element s в этом контексте. Когда закончите, вы можете полностью отобразить весь собранный визуал на RenderTargetBitmap.