2016-02-29 5 views
1

Problème:imprimer un formulaire à plus dpi que l'écran résolution

Nous avons besoin d'aide avec l'utilisation de la capacité de WinForms à auto-échelle différente de DPI pour nous permettre d'imprimer nos formulaires à 600dpi, plutôt qu'à l'écran DPI. Pour l'impression What-You-See-Is-What-You-Get, nous avons simplement pris notre fenêtre joliment aménagé et l'impression (éteindre les barres de défilement et les boutons et autres). Cela fonctionne très bien SAUF pour une chose: il sort à 96dpi ou 120dpi (quelle que soit la résolution de l'écran) ... l'un ou l'autre aspect granuleux et non professionnel (nos clients se plaignent). Et bien qu'il soit aussi lisible que ce qui serait à l'écran, vous vous attendez à ce que les documents imprimés soient plus lisibles qu'à l'écran ... vous devriez pouvoir voir des détails supplémentaires, lire des textes plus petits, etc.

Autres solutions envisagées:

Étant donné que nous avons beaucoup de travail auto-mise à l'échelle, de sorte que notre fenêtre se présente bien dans 96dpi, 120dpi, 144 dpi, etc., nous espérons que nous pouvions tirer notre fenêtre à 600dpi puis imprimer cette. OU, nous avons cherché à dessiner la fenêtre hors écran 5-6x plus grande que la normale de sorte que nous ayons le même nombre de pixels que 600dpi, mais à 96 ou 120 ppp ... mais en dessinant ensuite cette fenêtre géante à la page imprimée à 300 ou 600 dpi (quelle que soit l'imprimante).

Si vous pouvez nous dire comment faire l'une ou l'autre de ces alternatives, OU si vous pouvez nous donner un moyen différent d'atteindre notre objectif, nous l'apprécierions grandement.

Code actuel:

Dans le cas où il importe, notre formulaire se compose d'un FlowLayoutPanel pose d'autres FlowLayoutPanels plus petits dans les colonnes, les FlowLayoutPanels plus petites pose une seule colonne de TextBoxes, RichTextBoxes, un RichTextEditor tiers, PictureBoxes et DataGridViews. Nous utilisons une classe dérivée de PrintDocument implémentant OnBeginPrint, OnPrintPage et OnEndPrint. Dans OnPrintPage, il manipule notre fenêtre normale hors écran (ci-dessous et à droite des écrans réels) pour s'adapter à la taille de la page, puis demande à notre panneau principal (le FlowLayoutPanel supérieur) à DrawToBitmap, puis utilise l'objet Graphics transmis dans PrintEventArgs à DrawImage ce bitmap. Nous utilisons également Graphics.DrawString pour appliquer un pied de page à chaque page. Le code principal:

    using (Bitmap bm = new Bitmap(sz.Width, sz.Height)) 
        { 
         Rectangle rect = new Rectangle(0, 0, sz.Width, sz.Height); 
         mp.DrawToBitmap(bm, rect); 
         e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; // so footer is anti-aliased 
         e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // so when we scale up, we smooth out the jaggies somewhat 
         e.Graphics.DrawImage(bm, this.MarginBounds, rect, GraphicsUnit.Pixel); 
         if (this.Footer != null) 
          e.Graphics.DrawImage(this.Footer, this.FooterLocation); 
         if (!string.IsNullOrEmpty(pageNumber)) 
         { 
          e.Graphics.DrawString(pageNumber, KBStyle.Normal.Font, Brushes.Black, 
                this.MarginBounds.X, this.FooterLocation.Y + FooterOffset); 
         } 
        } 

Comment devrions-nous faire cela pour obtenir 600dpi à la page imprimée? (Ou même 300 dpi serait génial!)

Lorsque nous imprimons cela, il semble beaucoup mieux lorsqu'il est imprimé à partir d'une machine 120dpi que lorsqu'il est imprimé à partir d'une machine 96dpi, d'où nous savons qu'il imprime à la résolution d'écran. Mais nous nous demandons aussi s'il y a une façon simple de le dire: «Ce formulaire devrait dessiner à 600 dpi» et tout le reste du code ci-dessus fonctionne. Remarque: si nous prenons un métafichier EMF (métafichier amélioré) et l'imprimons à l'imprimante dans le code ci-dessus, cette EMF sort à 600 ppp. Malheureusement, nous n'avons pas trouvé de méthode DrawToEMF que nous pouvons appeler sur FlowLayoutPanel au lieu de DrawToBitmap. Changer la bitmap à 600dpi n'aide pas ... la méthode DrawToBitmap semble toujours dessiner le bitmap à la résolution de l'écran.

Merci!

+0

Vous ne pouvez pas convertir votre vue d'écran FlowLayoutPanel en vue imprimable. Vous devrez créer votre propre routine de dessin dans l'événement PrintPage à l'aide de la méthode DrawString. Pas de repas gratuit. – LarsTech

+0

@LarsTech, je ne suis pas sûr d'avoir compris votre commentaire ... DrawToBitmap fonctionne très bien sur un FlowLayoutPanel ... c'est beaucoup un "free lunch", pour ainsi dire ... c'était assez facile de le rendre imprimable (on l'utilise maintenant , avec succès). Dans le code ci-dessus, "mp" est un FlowLayoutPanel. Le seul problème est qu'il le fait à la résolution de l'écran. Et même si la taille de la fenêtre est plus grande (correspondant aux pixels de la page), nous semblons toujours se retrouver avec seulement une résolution d'écran. –

+0

Les imprimantes ont une bien meilleure résolution. Si vous voulez que les résolutions de l'imprimante soient attrayantes, vous devrez supprimer la routine DrawToBitmap où le texte est impliqué et commencer à utiliser les routines Printer DrawString. – LarsTech

Répondre

1

Bon, j'ai compris ... et ça marche très bien!

Je ne sais toujours pas comment créer un formulaire à 300 dpi et utiliser la fonctionnalité de mise à l'échelle automatique.

MAIS ...

J'ai prouvé que si vous créez la fenêtre 3.125x plus grande que nécessaire à 96 dpi, et l'échelle de la police jusqu'à 3.125x, et ainsi de suite, de sorte que tout est le nombre de pixels que vous feriez Même si votre écran est à 96dpi, vous pouvez utiliser la fonctionnalité normale Control.DrawToBitmap() pour le transformer en bitmap, puis vous pouvez utiliser le GDI Graphics.DrawImage (thatGiantBitmap, giantSrcRect, pageSizeDestRect) à l'objet Graphics de l'imprimante, et il va cartographier ces pixels géants de 96 dpi aux 300 dpi de la taille de la page, vous donnant une impression de 300 dpi. Parfait.

Pour l'un de nos fenêtres qui prennent en charge le redimensionnement et permettent à nos utilisateurs zoom le contenu arbitraire, puis imprimer What-You-See-Is-What-You-Get est facile:

Dans OnBeginPrint de votre PrintDocument , faire:

(1) dup en option, le formulaire afin de ne pas salir avec ce que l'utilisateur regarde

(2) Déplacer le formulaire que vous souhaitez imprimer à l'écran (ci-dessous et à droite de tous vos écrans)

(3) Définissez le formulaire pour qu'il dépasse la taille de l'écran (par défaut, WinForms ne deviendra pas plus grand que l'écran)

(4) Divisez 300 dpi par votre résolution d'écran pour obtenir la croissance facteur

(5) Développez votre formulaire par le facteur de croissance

(6) Zoom son contenu par facteur de croissance (si elles ne le font pas à l'échelle automatique/auto-zoom avec la taille du formulaire)

en OnPrintPage de votre PrintDocument, faire:

(7) Sur tout contrôle dans votre formulaire que vous voulez imprimer, faire DrawToBitmap() à un Bitmap la taille de ce contrôle

(8) Sur les e.Graphics font DrawImage (thatGiantBitmap, giantSrcRect, pageSizeDestRect)

Cet appel DrawImage dessine à la résolution de l'imprimante, si vous avez autant de pixels dans votre thatGiantBitmap. Dans ce cas, j'ai calculé le bitmap pour donner le nombre de pixels nécessaires pour 300 dpi, donc j'obtiendrai des impressions à 300 dpi même si l'imprimante est à 600 dpi. Si vous avez besoin de 600 dpi, utilisez 600 dpi dans le calcul de l'étape 4.

-3

Le total des estimations ici, mais qu'en est-il de l'utilisation de CSS? Je devine combien vous voulez mettre à l'échelle, et je ne sais pas comment vous savez quelle est l'échelle de l'imprimante. L'utilisation de la requête de support d'impression permet de l'imprimer mais laisse la vue d'écran seule.

@media print { 
    * { 
    transform: scale(2000px,2000px); 
    } 
} 
+1

OP demande une solution winforms, qui n'utilise pas css – JanR