Image Conversion Error on iOS printing a PNG file using IZebraPrinter.PrintImage

I am trying to print a PNG signature image using CPCL on a QLn420 using the LinkOS SDK for Xamarin on an iPhone. I can print the text part of the receipt using line print mode beautifully, but when I get to the point where I need to print my image, I get the following exception from the printer object:

 

Error - Error MSG: Error printing receipt | Exception: LinkOS.Plugin.ConnectionException: Image conversion error: Error writing to connection   at LinkOS.Plugin.ZebraPrinterImplementation.PrintImage (System.Object os_image, System.Int32 x, System.Int32 y, System.Int32 width, System.Int32 height, System.Boolean insideFormat) [0x00041] in <5ba493cd13a6476cb6f38f54ba338afd>:0 

 

The code I am using to attempt to print this image is this:

 

          private void PrintImage(IConnection connection, byte[] imageSource, int x, int y) {              var provider = new CGDataProvider(NSData.FromArray(imageSource));              var png = CGImage.FromPNG(provider, null, false, CGColorRenderingIntent.Default);                PrintImage(connection, png, x, y);          }            private void PrintImage(IConnection connection, CGImage zebraBitmap, int x, int y)          {              try {                  connection.TimeToWaitAfterWrite = 200;                    if (!connection.IsConnected)                      connection.Open();                    #region SignatureImage                  var printer = ZebraPrinterFactory.Current.GetInstance(PrinterLanguage.CPCL, connection);                  connection.Write(GetBytes("! U1 setvar \"device.languages\" \"cpcl\"\r\n"));                    printer.PrintImage(zebraBitmap, x, y, Convert.ToInt32(zebraBitmap.Width), Convert.ToInt32(zebraBitmap.Height), true);                  Thread.Sleep(3000);                    #endregion              }              finally {                  connection.Write(GetBytes("\r\n"));                  connection.Write(GetBytes("! U1 setvar \"device.languages\" \"line_print\"\r\n"));              }          }

 

This exact same code on the exact same printer works like a champ in my Android platform project.

 

Any help or suggestions would be most appreciated.

 

Thanks,

Matthew

Anonymous (not verified)
Hi Matthew,I don't see

Hi Matthew,

I don't see anything specifically wrong with your code

Is your imageSource a standard, non-compressed or encoded, png? This system assumes it is standard.

Here is my code for getting the CGImage in iOS, it does assume the image is already saved as a file, but your provider should also work:

        public object GetImage(string fileName)

        {

            CGImage image = null;

            fileName = fileName + ".png";

            image = new CGImage(400, 200, 1, 1, 400, CGColorSpace.CreateGenericRgbLinear(), CGBitmapFlags.First, CGDataProvider.FromFile(fileName), null, false, CGColorRenderingIntent.Default);

            return image;

        }

It looks fairly similar, but try it. 

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Matthew Belk
I don't believe the PNG is

I don't believe the PNG is compressed or encoded. We do do some resizing and alpha-channel removal with code like this:

        public async Task<byte[]> Resize(byte[] image, int newWidth)
        {
            return await Task.Factory.StartNew<byte[]>(() =>
            {
                var data = NSData.FromArray(image);

                var original = UIImage.LoadFromData(data);
                var width = original.CGImage.Width;
                var height = original.CGImage.Height;
                var ratio = (float)newWidth / (float)width;
                var newHeight = (int)(ratio * height);

                var resized = original.Scale(new CoreGraphics.CGSize(newWidth, newHeight));

                var png = resized.AsPNG();
                return png.ToArray();
            });
        }

        public async Task<byte[]> RemoveTransparency(byte[] image)
        {
            return await Task.Factory.StartNew<byte[]>(() =>
            {
                var data = NSData.FromArray(image);

                var original = UIImage.LoadFromData(data);

                UIGraphics.BeginImageContextWithOptions(original.Size, false, original.CurrentScale);

                var rect = new CGRect(0, 0, original.Size.Width, original.Size.Height);

                var context = UIGraphics.GetCurrentContext();
                context.SetFillColor(1, 1);
                context.FillRect(rect);
                original.Draw(rect, CGBlendMode.Normal, 1.0f);
                var newImage = UIGraphics.GetImageFromCurrentImageContext();
                UIGraphics.EndImageContext();

                var png = newImage.AsPNG();
                return png.ToArray();
            });
        }

before calling the PrintImage method.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Matthew Belk
No joy using your CGImage

No joy using your CGImage constructor. I am going to skip the transparency removal code to see if that's messing things up any.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Matthew Belk
Completely removed the

Completely removed the resizing and transparency removal steps and still get the same error.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Matthew Belk
Robin,Do you have any other

Robin,

Do you have any other suggestions for me on this? We're really starting to get some pressure from a customer to get the image printing working.

Thanks,

Matthew

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Matthew Belk
Robin,I think I solved this

Robin,

I think I solved this with the help of this Zebra KB article: https://km.zebra.com/kb/index?page=content&id=SO8786&actp=RSS

Zebra Technologies - Receiving EAOutputStream Error With Zebra iOS and Link-OS SDK

Once I put the PrintImage call into its own background thread, everything seems to work right on iOS.

-Matthew

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Log in to post comments