iosxamarinxamarin.iosuiprintinteractioncntrler

Can you resize images that are passed to UIPrintInteractionController.PrintingItems?


I'm trying to print multiple labels using UIPrintInteractionController.PrintingItems but when the image is loaded it fills the page, is it possible to have multiple images on one page using this method or is there another method that would offer me a better solution? Thanks.

  void Print()
    {
        var printInfo = UIPrintInfo.PrintInfo;
        printInfo.OutputType = UIPrintInfoOutputType.General;
        printInfo.JobName = "Label Printing";

        //UIPrintFormatter formatter = new UIPrintFormatter()
        //{
        //    StartPage = 0,
        //    ContentInsets = new UIEdgeInsets(72, 72, 72, 72),
        //    MaximumContentWidth = 6 * 72,

        //};

        int labelAmount = 10;
        int x;
        NSObject[] labelItems = new NSObject[labelAmount];
        for (x = 0; x < labelAmount; x++)
        {
            labelItems[x] = UIImage.FromFile("Images/BMcAzurri.png");
        }

        UIPrintInteractionController printer = UIPrintInteractionController.SharedPrintController;
        printer.PrintInfo = printInfo;
        //printer.PrintFormatter = formatter;
        printer.PrintingItems = labelItems;
        printer.ShowsPageRange = true;
        printer.Present(true, (handler, completed, err) => {
            if (!completed && err != null)
            {
                Console.WriteLine("error");
            }
        });
    }

Solution

  • There are a few ways to do what you are asking, here is just one using a graphics context to do your print page rendering.

    Example:

    var printInfo = UIPrintInfo.PrintInfo;
    printInfo.OutputType = UIPrintInfoOutputType.General;
    printInfo.JobName = "Label Printing";
    
    var uiImage = UIImage.FromFile("BingWallpaper-2017-05-04.jpg");
    var noColumns = 2;
    var noRows = 2;
    var gapBetweenImages = 25;
    int noOfPages = 2;
    NSObject[] labelItems = new NSObject[noOfPages];
    for (int x = 0; x < noOfPages; x++)
    {
        var aPrintView = new UIView
        {
            Frame = new CGRect(0, 0, (uiImage.Size.Width * noColumns) + ((noColumns + 1) * gapBetweenImages), (uiImage.Size.Height) * noRows + ((noRows + 1) * gapBetweenImages))
        };
        for (int column = 0; column < noColumns; column++)
        {
            for (int row = 0; row < noRows; row++)
            {
                var printImage = new UIImageView(uiImage)
                {
                    Frame = new CGRect((column * gapBetweenImages) + (column * uiImage.Size.Width), (row * gapBetweenImages) + (row * uiImage.Size.Height), uiImage.Size.Width, uiImage.Size.Height)
                };
                aPrintView.Add(printImage);
            }
        }
        UIGraphics.BeginImageContext(aPrintView.Bounds.Size);
        aPrintView.Layer.RenderInContext(UIGraphics.GetCurrentContext());
        var aPageImage = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();
        labelItems[x] = aPageImage;
    }
    
    UIPrintInteractionController printer = UIPrintInteractionController.SharedPrintController;
    printer.PrintInfo = printInfo;
    printer.PrintingItems = labelItems;
    printer.ShowsPageRange = true;
    printer.Present(true, (handler, completed, err) =>
    {
        if (!completed && err != null)
        {
            Console.WriteLine("error");
        }
    });
    

    Note: !!! This is not handling the clean up, make sure you Dispose of everything after you are done...

    Note: This is just a quick example does not handle the aspect ratio of the image to the paper size, you would need to consider that depending upon what you are printing and to what type of printer/paper...

    Note: If you were renderering a number of text fields vs. images, you might want to render to a PDF vs a UIImage and print that instead.

    enter image description here