ESC POS command ESC* for printing bit image on printer - printing

I want to print a bitmap logo file with ESC POS command ESC*.
Following is the link for technical documentation of the command.
https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=88
According to me, the printer requires the image data in the form of 1s and 0s. So, it prints a dot, with the occurrence of 1 and blank, with the occurrence of 0.
But I am not able to figure out how to send multi line bit image data with the help of above command, since the command accepts only the image data in the horizontal direction. Please help me with the problem.

ESC * is one of several "bit image" commands in ESC/POS. It accepts "column format" data, which can only represent a single line of either 8 or 24 pixels. So there are two good options here.
Print multiple lines using ESC *
It sounds like you are able to print one line, so I will assume that the data format itself is not an issue.
You can print multiple lines by simply repeating the command to print the extra lines, separated by line breaks \n. This requires chopping up the image, and padding it with whitespace so that it is a multiple of 8 or 24 pixels in height (again, due to the format).
Because of line spacing, you need to issue a command to change the size of line feeds during the image print, then another command to reset them at the end.
I use ESC 3 0x10 for 16-unit line feeds (bytes 0x1b 0x33 0x10) and ESC 2 (bytes 0x1b 0x32) to reset.
Example of column format bit image printing in Python using ESC *
Example of column format bit image printing in PHP using ESC *
This method of printing has excellent compatibility with old printers, but you can get some thin horizontal lines in the output.
Print the entire image with GS v 0
This bit image command accepts the different "raster format" data. I make use of the fact that the blob in this format is identical to the binary data in the widely implemented PBM bitmap format (specifically the binary data in files with the P4 header).
The height of the image will be limited by your print buffer size, but could go up to 65535 pixels. The width must be divisible by 8 because of the representation.
Example of raster format bit image printing in Python using VS v 0
Example of raster format bit image printing in PHP using GS v 0
Side note: These snippets the actual prototypes of the image processing code that now appears in the popular open source escpos-php and python-escpos libraries. Using an existing library has a number of benefits, and you should consider it if it's an option.

Related

Reading byte by byte HEIF/HEIC images XMP metadata

I am trying to build a native byte parser that given an HEIF image it returns back its metadata (mainly width and height of the image).
I am struggling a lot at the moment finding the right documentation and specs to use for parsing such info. I have to do such thing for both XMP and EXIF metadata, but let's focus only on XMP for now.
What I need is the exact byte structure of where to find what. According to the HEIF international standard doc (here):
For image items, XMP metadata shall be stored as an item of item_type value 'mime' and content type'application/rdf+xml'. The body of the item shall be a valid XMP document, in XML form.
Perfect, if I analyse a sample image I can find such marker:
From now on I can't find anywhere how to get the info I need. I would expect something saying "the first 2 bytes are the header, with marker 0xFF 0xCE (just an example), the next 2 bytes are the width, and following 2 bytes the height...etc".
In my case I am going by intuition. My sample image is of dimensions 8736x5856. If in the tool I look for Big-Endian 2 byte integer 8736, I can find it:
And hey, 2 bytes later there is the 5856 height as well:
But again, I arrived here by luck and intuition. I need a proper schema that tells me where to find what in such a way that I can traslate it to code.
What I think you'r seeing is a "mime" and "ispe" mp4 box as HEIF is ISOBMFF based. I would recommend looking at the file using a mp4 capable tool like mp4dump, HexFiend or fq (note: my tool). The "ispe" (Image Spatial Extents) box i probably what you want to read.
fq does no support ispe box yet but you could read it like this:
$ fq 'grep_by(.type=="ispe").data | tobytes | [.[-8:-4], .[-4:] | tonumber]' file.heif
[
8736,
5856
]
So what you need is probably a basic ISOBMFF reader and then look for the "ispe" box and decode it. If you'r only looking for the first of a specific box you can probably ignore that ISOBMFF is a tree structure.

NVIDIA NVENC (Media Foundation) encoded h.264 frames not decoded properly using VideoToolbox

I am facing the same problem as described here when trying to decode a frame on iPad Pro OS v14.3 (I am also using Olivia Stork's example):
25% of the picture data is decoded correctly, the rest of the picture is just green.
The decoded image on iPad Pro OS v14.3 looks like this (the image was converted and saved in the decoder callback as described here, so it's not just a displaying problem).
The original image looks like this.
The image is encoded with NVIDIA NVENC (Media Foundation) on Windows10.
I searched the frame picture data for additional 4-Byte NALU start codes as described in the link, but there are only the three expected ones for SPS, PPS and IDR picture data.
I have another Media Foundation decoder application running on Windows10 which can decode the frames from exactly the same source correctly.
I am struggling for days now finding the cause of the problem.. anyone any ideas?
Thanks in advance. Rob
-
EDIT 2021-01-11:
I figured out that there are actually three additional 3-byte start codes (0x000001) within in the IDR picture data block of NALU type 5.
I tried to replace these start codes with the length of the following data block (big endian), as described here, but with the same result.
I also tried adding Emulation Prevention Bytes (0x000001 => 0x000301) as described here, but that also made no difference.
Maybe I am mislead and these start codes have nothing to do with the issue.. at least they are not just random image data, because they always appear at the same position (index) in the picture data block. Currently I am running out of ideas.. any hint anybody?
-
EDIT 2021-01-14:
I figured out a few more things:
Out of sheer lack of ideas I copied the picture data followed after the last start code at the beginning of the block (right after after the 4-Byte NALU start code).
I had expected - if that would work at all - to see the last quarter of the original image at the top of the decoded image, but to my surprise the decoded image looked like this.
I tried the same with the picture data coming after the second and third start code, and the decoded image looked like this and this:
The image data is decoded correctly and it is even at the correct position (compare to original image).
Even if I strip off all 3-Byte start codes and copy the picture data concatenated after the 4-Byte start code, it's the same result, only 25% of the image is decoded. So the additional 3-Byte start codes are apparently not the problem. There must be some setting somewhere which tells the decoder to only decode 25% of the image. I would tip on the CMVideoFormatDescription, but as far as I can see it looks okay.
I am also wondering how the decoder knows where to display the different picture data blocks. Either there is an offset defined somewhere within the picture data or the xy-position of every pixel is added by the encoder somehow..
I managed to find the cause of the problem: The 3-Byte start codes in the IDE picture data block must be replaced by 4-Byte start codes.
So first replace all 3-Byte start codes by 4-Byte start codes.
Then replace the 4-Byte start codes with the length of the following data block (big endian). The slices should be arranged like this (as mentioned here by 'Blackie'):
[4byte slice1 size][slice1 data][4byte slice2 size][slice2 data]...[4byte slice4 size][slice4 data]
Remember to not include the start code length in slice size.
After changing that, my frame was completely displayed.
By the way:
The information where to display the different picture data blocks is specified in the header data of each NALU (parameter 'first_mb_in_slice').
There is a very good c# example here how to extract the NALU header data. You can almost copy it 1:1.

How can I scale an xpm image, retaining symbolic colour names

I'm trying to batch scale a load of xpm images to double pixel size. I can do this using ImageMagick like this:
convert infile.xpm -sample 200% outfile.xpm
However, the symbolic colour names are lost.
In the original input, the colour entries are as follows:
". c #007EBF s active_hilight_1",
"+ c #0A5E89 s active_color_1",
"# c #143D52 s active_shadow_1",
In the up-scaled version:
" c #143D52",
". c #0A5E89",
"X c #007EBF",
The colour names changed, which is fine, but as you can see the s <symbolic-name> suffixes are stripped.
Does anyone know a quick way to do this using ImageMagick or a similar (open-source) utility?
Thanks
EDIT: Seems ImageMagick can't due this due to a bug, but does anyone know any other tool which may be able to do this?
mogrify -sample 200% *.xpm
^ This works as long as you have a new (post 2019-09-02) version of ImageMagick with the xpm output bug fixed, as described here:
https://github.com/ImageMagick/ImageMagick/issues/1684
Today's master branch, for example, passes symbolic colour names through properly.

How to change screening (halftone pattern) of my printer Cups driver?

I am using CUPS with the printer driver which use "application/vnd.cups-raster 10 rastertopj" and i am trying to get the look of dither 4x4 print/output but i am clueless where to change the setting for choosing different dithering/halftoning pattern..
i also contacted the cups and they said dithering is done by the driver and also told that If the driver is Ghostscript-based you may be able to change the dither as you’d like, and yes this is indeed Ghostscript-based printer driver/filter cause when i open .PPD file i see *Product: "(ESP Ghostscript)".
Can you please guide me on how or where to change the dither of the printer filter/driver?
Edited:
this is the halftone output its printing: https://imgur.com/a/18hkC1H or https://imgur.com/download/7pTksX4
this is the output i am looking for: https://imgur.com/a/KZTQrkp or https://imgur.com/download/5FnpKEM
Thankyou
Ghostscript supports the full range of halftoning defined in the PostScript Language Reference Manual. It also has its own stochastic screening code.
To change the screening, you put the relevant commands in the PostScript file. If you are starting with a PostScript program, then that's where you put the screening. Otherwise you'll have to inject it into the PostScript, which is where you modify the PPD file.
I can't tell you how to do that (because its a CUPS thing, not Ghostscript), nor can I tell you what the PostScript you need is (because I have no idea what the screen you want looks like), you'll have to experiment to match the output you want (note that halftoning is not the same as dithering). Worst case you can use a type 3 halftone dictionary which should produce something similar to what you want, at the cost of needing a lot of data to set it up.
<<
/HalftoneType 1
/Frequency 37
/Angle 45
/SpotFunction {180 mul cos
exch 180 mul cos
add 2 div}
>> sethalftone
For what its worth, the above is a type 1 halftone dictionary defining a round spot shape and with what I beleive are 'reasonable' values for a 300 dpi monochrome output device.
As to how you get that into the PostScript that Cups sends to Ghostscript, or onto the Ghostscript command line, I can't tell you.

Intermec PB51 says it has 864 dots across but it has only 832

I am printing images on an Intermec PB51 using ESC/P language.
In the ESC V command specification, it says:
After the printer receives this command, the printer dumps the binary
data supplied directly to the printhead. Graphics printed with this
command must be the exact width of the printhead in bits.
The printhead query command (PH?) replies with a TD parameter that is documented as
TD: Total number of dots across the printhead.
When I send the printhead query command to my Intermec PB51, it responses with 0864 as the total number of dots, but when i use 864 as the printer width in my image printing function, the image is screwed up and (as I seem to send too many bytes, the printer is in an invalid state afterwards).
Choosing a value of 832 prints the image just fine. Now the question is, where are those extra 32 bits (4 bytes) coming from?
Below find an image print with hardcoding dotsAcross to 832
If I use 864, as the printer suggests, the output looks like this

Resources