2011-07-02 17 views
10

Próbuję przekonwertować XPS z WPF.Jak przekonwertować plik XPS na obraz w wysokiej jakości (zamiast rozmytej niskiej rozdzielczości)?

Chodzi o to, że te obrazy mogą być ładowane z Silverlight 4, dla tego używam następujący kod:

// XPS Document 
      XpsDocument xpsDoc = new XpsDocument(xpsFileName, System.IO.FileAccess.Read); 
      FixedDocumentSequence docSeq = xpsDoc.GetFixedDocumentSequence(); 

     // The number of pages 
     PageCount = docSeq.References[0].GetDocument(false).Pages.Count; 

     DocumentPage sizePage = docSeq.DocumentPaginator.GetPage(0); 
     PageHeight = sizePage.Size.Height; 
     PageWidth = sizePage.Size.Width; 
     // Scale dimensions from 96 dpi to 600 dpi. 
     double scale = 300/ 96; 

     // Convert a XPS page to a PNG file 
     for (int pageNum = 0; pageNum < PageCount; pageNum++) 
     { 
      DocumentPage docPage = docSeq.DocumentPaginator.GetPage(pageNum); 
      BitmapImage bitmap = new BitmapImage(); 
      RenderTargetBitmap renderTarget = 
       new RenderTargetBitmap((int)(scale * (docPage.Size.Height + 1)), 
                   (int)(scale * (docPage.Size.Height + 1)), 
                   scale * 96, 
                   scale * 96, PixelFormats.Pbgra32); 
      renderTarget.Render(docPage.Visual); 


      PngBitmapEncoder encoder = new PngBitmapEncoder(); 

      encoder.Frames.Add(BitmapFrame.Create(renderTarget)); 

      FileStream pageOutStream = new FileStream(name + ".Page" + pageNum + ".png", FileMode.Create, FileAccess.Write); 
      encoder.Save(pageOutStream); 
      pageOutStream.Close(); 

Ten kod jest pobierana z http://xpsreader.codeplex.com/ projekt do konwertowania dokumentu XPS. działa świetnie! Problem polega jednak na tym, że obraz ma niską rozdzielczość i jest niewyraźny. badałem i stwierdził, że RenderTargetBitmap i znaleźć na tej stronie: http://www.codeproject.com/Questions/213737/Render-target-bitmap-quality-issues

Chodzi tu masz to nie używa sprzętu RenderTargetBitmap rendering.

Jednym z rozwiązań jest użycie DirectX z WPF, ale nie znalazłem żadnego wyraźnego przykładu, który wskaże mi właściwą drogę.

Doceniam sugestie. Z góry dziękuję.

Aktualizacja: I załączeniu dokument XPS, próbuję przekonwertować obraz Please download test.xps

+0

Próbujesz renderowanie przy 1800 dpi. To jest kompletna przesada - wszystko powyżej 300 dpi będzie przesadą, chyba że planujesz powiększanie drogi na ekranie. – Jon

+0

Masz rację, że przy 300 dpi eksperymentowałeś z różnymi wartościami z sugestiami? –

+1

Jeśli chcesz zrobić to w trybie offline (i platforma krzyżowa), możesz użyć programu ghostscript, który obsługuje XPS w późniejszych wersjach. Zobacz: http://www.ghostscript.com/GPL_Ghostscript_8.61.html –

Odpowiedz

4

widziałem w tym poście iw wielu innych, że ludzie mają problemy z konwersją DocumentPage do obrazu i zapisanie go na dysku twardym. Ta metoda pobierała wszystkie strony z przeglądarki dokumentów i zapisywała je na dysku twardym jako obrazy jpg.

public void SaveDocumentPagesToImages(IDocumentPaginatorSource document, string dirPath) 
    { 
     if (string.IsNullOrEmpty(dirPath)) return; 

     if (dirPath[dirPath.Length - 1] != '\\') 
      dirPath += "\\"; 

     if (!Directory.Exists(dirPath)) return; 

     MemoryStream[] streams = null; 
     try 
     { 
      int pageCount = document.DocumentPaginator.PageCount; 
      DocumentPage[] pages = new DocumentPage[pageCount]; 
      for (int i = 0; i < pageCount; i++) 
       pages[i] = document.DocumentPaginator.GetPage(i); 

      streams = new MemoryStream[pages.Count()]; 

      for (int i = 0; i < pages.Count(); i++) 
      { 
       DocumentPage source = pages[i]; 
       streams[i] = new MemoryStream(); 

       RenderTargetBitmap renderTarget = 
        new RenderTargetBitmap((int)source.Size.Width, 
              (int)source.Size.Height, 
              96, // WPF (Avalon) units are 96dpi based 
              96, 
              System.Windows.Media.PixelFormats.Default); 

       renderTarget.Render(source.Visual); 

       JpegBitmapEncoder encoder = new JpegBitmapEncoder(); // Choose type here ie: JpegBitmapEncoder, etc 
       encoder.QualityLevel = 100; 
       encoder.Frames.Add(BitmapFrame.Create(renderTarget)); 

       encoder.Save(streams[i]); 

       FileStream file = new FileStream(dirPath + "Page_" + (i+1) + ".jpg", FileMode.CreateNew); 
       file.Write(streams[i].GetBuffer(), 0, (int)streams[i].Length); 
       file.Close(); 

       streams[i].Position = 0; 
      } 
     } 
     catch (Exception e1) 
     { 
      throw e1; 
     } 
     finally 
     { 
      if (streams != null) 
      { 
       foreach (MemoryStream stream in streams) 
       { 
        stream.Close(); 
        stream.Dispose(); 
       } 
      } 
     } 
    } 
Powiązane problemy