Alla fine ho capito che esiste un'opzione che affronta il mio requisito generale di incorporare un formato vettoriale in un lavoro di stampa, ma non funziona con la stampa basata su GDI.
Il formato di file XPS creato dal driver di stampa Microsoft XPS Writer può essere stampato da WPF, utilizzando ReachFramework.dll incluso in .NET. Utilizzando WPF per la stampa anziché GDI, è possibile incorporare una pagina del documento XPS in un documento di stampa più grande.
Lo svantaggio è che la stampa WPF funziona in modo un po 'diverso, quindi tutto il codice di supporto che utilizza direttamente elementi nello spazio dei nomi Sytem.Drawing deve essere riscritto.
Ecco lo schema di base di come incorporare il documento XPS:
Aprire il documento:
XpsDocument xpsDoc = new XpsDocument(filename, System.IO.FileAccess.Read);
var document = xpsDoc.GetFixedDocumentSequence().DocumentPaginator;
// pass the document into a custom DocumentPaginator that will decide
// what order to print the pages:
var mypaginator = new myDocumentPaginator(new DocumentPaginator[] { document });
// pass the paginator into PrintDialog.PrintDocument() to do the actual printing:
new PrintDialog().PrintDocument(mypaginator, "printjobname");
quindi creare un discendente di DocumentPaginator, che farà la stampa vera e propria.Sovrascrivi i metodi astratti, in particolare GetPage dovrebbe restituire DocumentPages nell'ordine corretto. Ecco il mio codice di prova che dimostra come aggiungere contenuti personalizzati a un elenco di documenti XPS:
public override DocumentPage GetPage(int pageNumber)
{
for (int i = 0; i < children.Count; i++)
{
if (pageNumber >= pageCounts[i])
pageNumber -= pageCounts[i];
else
return FixFixedPage(children[i].GetPage(pageNumber));
}
if (pageNumber < PageCount)
{
DrawingVisual dv = new DrawingVisual();
var dc = dv.Drawing.Append();
dc = dv.RenderOpen();
DoRender(pageNumber, dc); // some method to render stuff to the DrawingContext
dc.Close();
return new DocumentPage(dv);
}
return null;
}
Quando si tenta di stampare su un altro documento XPS, dà un'eccezione "FixedPage non può contenere un altro FixedPage", e un messaggio di H.Alipourian dimostra come risolvere il problema: http://social.msdn.microsoft.com/Forums/da/wpf/thread/841e804b-9130-4476-8709-0d2854c11582
private DocumentPage FixFixedPage(DocumentPage page)
{
if (!(page.Visual is FixedPage))
return page;
// Create a new ContainerVisual as a new parent for page children
var cv = new ContainerVisual();
foreach (var child in ((FixedPage)page.Visual).Children)
{
// Make a shallow clone of the child using reflection
var childClone = (UIElement)child.GetType().GetMethod(
"MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic
).Invoke(child, null);
// Setting the parent of the cloned child to the created ContainerVisual
// by using Reflection.
// WARNING: If we use Add and Remove methods on the FixedPage.Children,
// for some reason it will throw an exception concerning event handlers
// after the printing job has finished.
var parentField = childClone.GetType().GetField(
"_parent", BindingFlags.Instance | BindingFlags.NonPublic);
if (parentField != null)
{
parentField.SetValue(childClone, null);
cv.Children.Add(childClone);
}
}
return new DocumentPage(cv, page.Size, page.BleedBox, page.ContentBox);
}
dispiace che non è esattamente la compilazione del codice, volevo solo fornire una panoramica dei pezzi di codice necessario per farlo funzionare per dare ad altre persone una testa inizia su tutti i pezzi disparati che devono venire insieme per farlo funzionare. Cercare di creare una soluzione più generalizzata sarebbe molto più complesso dello scopo di questa risposta.
facciamo qualcosa di simile, ma rendiamo il PDF prima di tutto in un bitmap: il problema della qualità può essere ottenuto quando si esegue il rendering utilizzando una libreria di alta qualità più un valore di alta risoluzione (minimo 305, migliore 1200) che costa un po 'di memoria/prestazioni ... – Yahia
Ho notato l'altro giorno che PDFCreator (http://sourceforge.net/projects/pdfcreator/), nonostante sia principalmente finalizzato alla creazione di PDF, può essere effettivamente utilizzato per stampare documenti PDF in una vasta gamma di formati, tra cui Immagini SVG e bitmap. Potrebbe meritare un'occhiata. –
Questi PDF tendono ad essere di testo con alcune linee art. Avrebbero anche stampato più di 1000 volte di seguito. La conversione di un PDF da 30 KB in una bitmap da 5 MB probabilmente porterebbe l'intera coda di stampa in ginocchio. –