VisualBrush Ресурсы, не включенные в Visual в XPS для преобразования растровых изображений
ОБНОВЛЕНИЕ: Мы заменили Генерацию изображений на альтернативу, которая решает проблему (PDF на изображение), но я собираюсь оставить этот вопрос открытым, поскольку я хотел бы понять, возможно ли это.
На нашем веб-сайте http://www.cloudformatter.com/ мы пытались внедрить некоторый код для обработки сгенерированных нами файлов XPS в изображение. Почти все работает хорошо, за исключением SVG на странице, которые включены в документ XPS через ресурсы VisualBrush.
Мы взяли за основу код здесь и некоторые другие из XPS для изображения
Ниже приведен код нашего конвертера, который создает пакет изображений страниц для ответа REST через этот веб-сайт. XPS в порядке, и большинство всех страниц работают, как ожидается, для изображения, поэтому код работает в настоящее время для всего, кроме SVG на страницах. Я должен отметить, что тот же код, который генерирует XPS для загрузки, генерирует поток, подаваемый в приведенный ниже код, чтобы он не нарушался при входе. Даже проверка Visual in 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 ответ
Частично. Когда ты получил свой 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
с этим контекстом. Когда закончите, вы можете визуализировать весь собранный визуал в RenderTargetBitmap
отлично.