web-dev-qa-db-fra.com

Impression d'image avec PrintDocument. comment ajuster l'image au format du papier

En C #, j'essaie d'imprimer une image en utilisant la classe PrintDocument avec le code ci-dessous. L'image est de taille 1200 px largeur et 1800 px hauteur. J'essaie d'imprimer cette image sur un papier 4 * 6 à l'aide d'une petite imprimante zeebra. Mais le programme imprime seulement 4 * 6 sont de la grande image. cela signifie qu'il n'ajuste pas l'image au format du papier!

     PrintDocument pd = new PrintDocument();
     pd.PrintPage += (sender, args) =>
     {
           Image i = Image.FromFile("C://tesimage.PNG");
           Point p = new Point(100, 100);
           args.Graphics.DrawImage(i, 10, 10, i.Width, i.Height);
     };
     pd.Print();

Lorsque j'imprime la même image à l'aide de Window Print (cliquez avec le bouton droit de la souris et sélectionnez imprimer, elle se met automatiquement à l'échelle pour le format de papier et s'imprime correctement.

29
Happy

Les paramètres que vous transmettez à la méthode DrawImage doivent être la taille souhaitée pour l'image sur le papier plutôt que la taille de l'image elle-même, la commande DrawImage se chargera ensuite de la mise à l'échelle pour vous. La façon la plus simple est probablement d'utiliser la substitution suivante de la commande DrawImage.

args.Graphics.DrawImage(i, args.MarginBounds);

Remarque: Cela faussera l'image si les proportions de l'image ne sont pas les mêmes que celles du rectangle. Quelques calculs simples sur la taille de l'image et la taille du papier vous permettront de créer un nouveau rectangle qui s'inscrit dans les limites du papier sans biaiser l'image.

33
BBoy

Ne pas piétiner la réponse déjà décente de BBoy, mais j'ai fait le code qui maintient le rapport d'aspect. J'ai pris sa suggestion, alors il devrait obtenir un crédit partiel ici!

PrintDocument pd = new PrintDocument();
pd.DefaultPageSettings.PrinterSettings.PrinterName = "Printer Name";
pd.DefaultPageSettings.Landscape = true; //or false!
pd.PrintPage += (sender, args) =>
{
    Image i = Image.FromFile(@"C:\...\...\image.jpg");
    Rectangle m = args.MarginBounds;

    if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
    {
        m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
    }
    else
    {
        m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
    }
    args.Graphics.DrawImage(i, m);
};
pd.Print();
24
psyklopz

La solution fournie par BBoy fonctionne très bien. Mais dans mon cas, j'ai dû utiliser

e.Graphics.DrawImage(memoryImage, e.PageBounds);

Cela imprimera uniquement le formulaire. Lorsque j'utilise MarginBounds, il imprime la totalité de l'écran même si le formulaire est plus petit que l'écran du moniteur. PageBounds a résolu ce problème. Merci à BBoy!

6
TonyM

Vous pouvez utiliser mon code ici

//Print Button Event Handeler
private void btnPrint_Click(object sender, EventArgs e)
{
    PrintDocument pd = new PrintDocument();
    pd.PrintPage += PrintPage;
    //here to select the printer attached to user PC
    PrintDialog printDialog1 = new PrintDialog();
    printDialog1.Document = pd;
    DialogResult result = printDialog1.ShowDialog();
    if (result == DialogResult.OK)
    {
        pd.Print();//this will trigger the Print Event handeler PrintPage
    }
}

//The Print Event handeler
private void PrintPage(object o, PrintPageEventArgs e)
{
    try
    {
        if (File.Exists(this.ImagePath))
        {
            //Load the image from the file
            System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\myimage.jpg");

            //Adjust the size of the image to the page to print the full image without loosing any part of it
            Rectangle m = e.MarginBounds;

            if ((double)img.Width / (double)img.Height > (double)m.Width / (double)m.Height) // image is wider
            {
                m.Height = (int)((double)img.Height / (double)img.Width * (double)m.Width);
            }
            else
            {
                m.Width = (int)((double)img.Width / (double)img.Height * (double)m.Height);
            }
            e.Graphics.DrawImage(img, m);
        }
    }
    catch (Exception)
    {

    }
}
4
Anas Naguib

Répondre:

public void Print(string FileName)
{
    StringBuilder logMessage = new StringBuilder();
    logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ START - {0} - {1} -------------------]", MethodBase.GetCurrentMethod(), DateTime.Now.ToShortDateString()));
    logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "Parameter: 1: [Name - {0}, Value - {1}", "None]", Convert.ToString("")));

    try
    {
        if (string.IsNullOrWhiteSpace(FileName)) return; // Prevents execution of below statements if filename is not selected.

        PrintDocument pd = new PrintDocument();

        //Disable the printing document pop-up dialog shown during printing.
        PrintController printController = new StandardPrintController();
        pd.PrintController = printController;

        //For testing only: Hardcoded set paper size to particular paper.
        //pd.PrinterSettings.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);
        //pd.DefaultPageSettings.PaperSize = new PaperSize("Custom 6x4", 720, 478);

        pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
        pd.PrinterSettings.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);

        pd.PrintPage += (sndr, args) =>
        {
            System.Drawing.Image i = System.Drawing.Image.FromFile(FileName);

            //Adjust the size of the image to the page to print the full image without loosing any part of the image.
            System.Drawing.Rectangle m = args.MarginBounds;

            //Logic below maintains Aspect Ratio.
            if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
            {
                m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
            }
            else
            {
                m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
            }
            //Calculating optimal orientation.
            pd.DefaultPageSettings.Landscape = m.Width > m.Height;
            //Putting image in center of page.
            m.Y = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Height - m.Height) / 2);
            m.X = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Width - m.Width) / 2);
            args.Graphics.DrawImage(i, m);
        };
        pd.Print();
    }
    catch (Exception ex)
    {
        log.ErrorFormat("Error : {0}\n By : {1}-{2}", ex.ToString(), this.GetType(), MethodBase.GetCurrentMethod().Name);
    }
    finally
    {
        logMessage.AppendLine(string.Format(CultureInfo.InvariantCulture, "-------------------[ END  - {0} - {1} -------------------]", MethodBase.GetCurrentMethod().Name, DateTime.Now.ToShortDateString()));
        log.Info(logMessage.ToString());
    }
}
4
KhanSahib

D'accord avec TonyM et BBoy - c'est la bonne réponse pour l'impression originale 4 * 6 de l'étiquette. (args.PageBounds). Cela a fonctionné pour moi pour l'impression des étiquettes d'expédition du service API Endicia.

private void SubmitResponseToPrinter(ILabelRequestResponse response)
    {
        PrintDocument pd = new PrintDocument();
        pd.PrintPage += (sender, args) =>
        {
            Image i = Image.FromFile(response.Labels[0].FullPathFileName.Trim());
            args.Graphics.DrawImage(i, args.PageBounds);
        };
        pd.Print();
    }
4
user1807576