PrinterToPDF
PrinterToPDF copied to clipboard
Page size and margins
So far the program pays no respect to page setup. I've prepared a new ESC/P2 sample from our labeling software:
The lable itself is 45x45mm.
They are arranged on a page with 4 columns and 6 rows, 24 labels on one page.
Distance from the left side of the outmost left label to the right side of the outmost right label it is 186mm.
Page length is 12" = 304.8mm.
Meaning there is a top margin of 2.9mm, a distance between the rable rows of 5.8mm and a bottom margin of 2.9mm again.
Left and right margin is a little difficult, because on line printers you could always move the paper horizontally.
But one can calculate that there is a 2mm distance between the label columns.
Here is a scan of such a page I created with a matrix printer (no ink - for higher precision):
Scan isn't as good as I thought. I may have to repeat it with higher contrast to show the paper and labels.
Here is a new scan of the same page, showing paper limits (top and right have been enhanced manually):
To help with page size and margins I have created another document with Word for DOS using EPLQ.DBS and selecting "LQ-series (multifont.) 1.0" as printer modell. It is a colour mix of text and graphic, resolution 360x180:
This is on a DIN A4 page (210 x 297mm). Top and bottom margin is 7.5mm, right margin is 20.1mm, left margin is 20mm.
Picture is scaled to 173.4 x 130 mm and centered, it is a screenshot of your website colour reduced to fixed eight colours using Stucki algorithm.
Can be used for testing colour as well, see https://github.com/RWAP/PrinterToPDF/issues/8
The program currently ignores top and bottom margins and paper size settings passed as ESC ( C command. However, the left and right margins are set.
I have started a method in the initialize() function to set up the paper sizes - standard margins could also be set here - as many printers rely on these being set through DIP switch settings, it is impossible to automate these unless they are passed by the printer program itself.
I completely understand. But as you can see from the RETRO.zip sample an A4 page still splits to three png/pdf files.
I would suggest 12" paper to be default for the program because at the time of ESC/P(2) that was the main page/paper format used.
The latest beta version of the software adheres to the top, bottom and side margins. You can set them up for the given page size in the initialize() routine. I have added default offsets in there according to the ESC/P2 programming reference manual, along with support for A4, A4 landscape and 12" paper sizes - more can easily be added
As part of the re-consideration of the PNG to PDF conversion routine, we need to look at how to set up the paper sizes passed to the PDF to ensure these are correct - see: http://www.imagemagick.org/script/command-line-options.php#page
We need to pass parameters if we are continuing to use ImageMagick...
Opening the pdf with Adobe Acrobat showes the file like this:
The document has a size of 2,100.4 x 2,969.3 mm. One could print it using "Fit to Printable Area" but that influences the original size of the print. Trying to print on lables would be completely impossible.
Opening the png in gimp showes that the file is
5954 x 8417px 2100,44 x 2969,33mm with a resolution of 72dpi
Setting resolution to 720dpi will not affect the pixels but will correct the size in mm to
210,04 x 296,93mm
I think that is required here.
This will need to be looked at once we have decided on the PNG to PDF conversion routine.
For now - we need to add page sizes to the initialize() routine and can then pass that to the convert command.
I have taken gimp to set the original PNG file to 720dpi. After that I used
convert input.png output.pdf
to convert it to PDF. Here is the result:
So as far as I see, all you have to do is set the PNG to 720dpi resolution.
Now that I've done above step. I was able to join the PNG with my scan:
I have coloured you PNG in green below that is my original scan. I wouldn't have expected this result.
The latest source now includes setting the PNG resolution to 720dpi - does this help?
1st - Can confirm that resolution now is 720dpi.
2nd - I am back to black background now.
3rd - It is difficult to match both scan and converted image when conversion result is a black page. ;-)
I am at a complete loss as to why you sometimes do not get a white background as this is not something I can replicate.
If you add line 554:
if (pixelColour==WHITE) printf("WHITE is %d %d %d \n",red(pixelColour), green(pixelColour), blue(pixelColour));
Do you see lots of output with WHITE is 255 255 255 ?
Had to change that to
for (x=0 ; x<width ; x++) { pixelColour = rgb[ipos + x]; if (pixelColour==WHITE) printf("WHITE is %d %d %d \n",red[pixelColour], green[pixelColour], blue[pixelColour]); row[ppos++] = red[pixelColour]; row[ppos++] = green[pixelColour]; row[ppos++] = blue[pixelColour]; }
because of
gcc PrinterConvert.c sdl-config --cflags --libs
-o PrinterConvert -lrt -lpng
PrinterConvert.c: In function ‘write_png’: PrinterConvert.c:554: error: called object ‘red’ is not a function PrinterConvert.c:554: error: called object ‘green’ is not a function PrinterConvert.c:554: error: called object ‘blue’ is not a function
Here is the output:
time ./PrinterConvert 4 3 SIEMENS.C16 1 sdloff ./
delays around ack: t1=0 t2=0 t3=0 t4=0 t5=0 write = png/page1.png command = convert png/page1.png ./pdf/page1.pdf
I am at page 2 write = png/page2.png command = convert png/page2.png ./pdf/page2.pdf
real 0m57.294s user 0m42.819s sys 0m3.736s
OK sorry for the typo.
However, the output is really odd - as it suggests the page is not getting set to white with erasepage() - called in line 408 and line 2192 (408 is actually overkill).
Just check that the program is actually running line 554 and see what the value of pixelColour is - maybe it is stuck at zero!
First I have amended the source as follows:
for (x=0 ; x<width ; x++) { pixelColour = rgb[ipos + x]; if (x==width) printf("I am here"); if (pixelColour==WHITE) printf("WHITE is %d %d %d \n",red[pixelColour], green[pixelColour], blue[pixelColour]); row[ppos++] = red[pixelColour]; row[ppos++] = green[pixelColour]; row[ppos++] = blue[pixelColour]; }
Result:
I am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am hereI am here...
So that is clear.
Then I tried to print pixelColour:
for (x=0 ; x<width ; x++) { pixelColour = rgb[ipos + x]; printf(pixelColour); if (pixelColour==128) printf("WHITE is %d %d %d \n",red[pixelColour], green[pixelColour], blue[pixelColour]); row[ppos++] = red[pixelColour]; row[ppos++] = green[pixelColour]; row[ppos++] = blue[pixelColour]; }
Result
gcc PrinterConvert.c sdl-config --cflags --libs
-o PrinterConvert -lrt -lpng
PrinterConvert.c: In function ‘write_png’:
PrinterConvert.c:554: warning: passing argument 1 of ‘printf’ makes pointer from integer without a cast
So I changed to
for (x=0 ; x<width ; x++) { pixelColour = rgb[ipos + x]; printf("%u ", pixelColour); if (pixelColour==128) printf("WHITE is %d %d %d \n",red[pixelColour], green[pixelColour], blue[pixelColour]); row[ppos++] = red[pixelColour]; row[ppos++] = green[pixelColour]; row[ppos++] = blue[pixelColour]; }
Which printed a lot of integers. And I changed again
for (x=0 ; x<width ; x++) { pixelColour = rgb[ipos + x]; if (pixelColour>=32) printf("%u ", pixelColour); if (pixelColour==128) printf("WHITE is %d %d %d \n",red[pixelColour], green[pixelColour], blue[pixelColour]); row[ppos++] = red[pixelColour]; row[ppos++] = green[pixelColour]; row[ppos++] = blue[pixelColour]; }
Which printed nothing! So that must be C specific. The variable is not what you think.
Hmm ...
pixelColour does of course depend on what colours you are using - bit 0 = black, bit 1= magenta, bit 2 = cyan, bit 3 = voilet, bit 4 = yellow, bit 5= red, bit 6 = green, bit 7 = white
So, pixelColour >=32 is only valid for printing green and white or mixed colours including green.
I wonder if pixelColour == 0 on your system for some reason when it should be a white background - this could be overcome by changing the start of lookupColour() to read:
int * lookupColour(unsigned char colourValue)
{
// Convert printer colour (0 to 7 stored in bits of colourValue) to RGB value
// Routine uses averaging to get colours such as pink (red + white)
static int rgb1[3];
int colourMixMethod = 2; // 1 = RGB simple addition method, 2 = Standard CMYK Mix with conversion -
int *mixedColour;
int mixedColour_red, mixedColour_green, mixedColour_blue;
rgb1[0]=0;
rgb1[1]=0;
rgb1[2]=0;
int mixColour = 0;
if (colourValue == 1) return rgb1; // Black
if (colourValue == 0 || colourValue == WHITE) {
// Bit 7 is set for white - not supported on printers
rgb1[0]=255;
rgb1[1]=255;
rgb1[2]=255;
return rgb1;
}
This should not actually happen unless it is a bug in your version of gcc causing an issue with the erasepage() function (which should have set bit 7 in all of the memory values initially)
Of course, it could also be a bug in the new CMYK lookup method for colour mixing - is the problem fixed by altering line 186 to read:
int colourMixMethod = 1;
If so then at least we know where to look for a bug....
I have just noticed that line 177 ( rgb_result[3] = rgb_lookups[3];) is not required and might cause an issue
is the problem fixed by altering line 186 to read:
int colourMixMethod = 1;
No!
I have just noticed that line 177 ( rgb_result[3] = rgb_lookups[3];) is not required and might cause an issue
// rgb_result[3] = rgb_lookups[3];
No difference! (still black)
Tried your amended
lookupColour
from above. No difference! (still black)
Remember, we were on white background. What happened after that?
Nothing that I can find in the history of the code - that is what is confusing!
Did you try the change to the lookupColour() function?
Did you try the change to the lookupColour() function?
Yes, as written above.
Sorry, but I did not archive the version that produces proper white background. I have only found the version that creates green background.
If you go to : https://github.com/RWAP/PrinterToPDF/blob/master/PrinterConvert.c
You can then click on history and will see the various update history on github. Click on the title of one (say "Improvements to colour and TIFF compression" on 11th May which is when I know the white background was working).
This shows the changes made in that version.
Click on browse files (top right) and that will take you to a snapshot of the code at that version - you can then access the full printerconvert.c at that time.
My guess is that this issue has come back in the commit of 14th May ( 720dpi Delta Row Compression ) although that is a pure guess
This
Commits on May 11, 2017 "Correction of Delta Row Compression"
https://raw.githubusercontent.com/RWAP/PrinterToPDF/76a89ccde0f810e05f6d5ebcf40d4edafecb5cf9/PrinterConvert.c
produces WHITE background.
This
Commits on May 12, 2017 "Colour Lookup & Page Size"
https://raw.githubusercontent.com/RWAP/PrinterToPDF/c008fc5a72299203735f64dd5a04aa7780d78289/PrinterConvert.c
produces BLACK background again.
That solves the Problem!
Changing line 471 from
int pixelColour;
to read
unsigned char pixelColour;
OK the black background is now fixed by changing line 471 from :
int pixelColour;
to read:
unsigned char pixelColour;
Not quite sure why this was needed on some versions of gcc
Now that I can "see" again, I've repeated my above test:
Green is the result of the conversion, black is my scan. The conversion in comparison to the printer showes a wider and higher picture.
I've done some measurements and found that the conversion is about 20% bigger than the original. I think it must have to do with the resolution?
720/120*100=600, where 720dpi is conversion and 600dpi is scan. I'll try to resize and overlay tomorrow.
Ok, so what I've done now comes closer to what is required. But I am a little puzzled about how I reached the result:
Changing the scan to 720dpi with gimp did not work. In fact I had to scale the scan to 120% of it's original size. But 120% seems not to be perfect value as you can see on above picture.
Any idea why?
Next step I did was to scale the converted (green) layer down to fit the scan.
Original size 5954 x 8417
fitted 5971 x 8394
Not very much, but this way scan and conversion matches. What I recognized doing this is that the converted png has a resolution of 719.998dpi:
Can that cause the problem?
Possibly the converted png resolution might have a bearing - we tell it to use 720dpi, but obviously libpng is not using that exact figure... However, at 720dpi, A4 paper (11.69") gives a vertical number of pixels of 11.69 * 720 = 8416.8 (slightly less using 719.988dpi but still more than 8416)
At 5971 x 8394 this gives an original paper size of 8.293" x 11.658" - which could of course be down to the physical size of your fanfold paper
I think it is a matter of working out the exact paper size - you said your paper is 12" fanfold, yet it measures (looking at your image) 205mm x 305mm = 8.07" x 12.0079" so you need to ensure that in initialize() you set the pageSize=2 and probably finetune the values in:
// 12" Paper - Fanfold
pageSetWidth = 5954; // 720 * 8.27"
pageSetHeight = 8640; // 720 * 12"
defaultMarginLeftp = 85; // 720 x 3mm
defaultMarginRightp = pageSetWidth - 85; // 720 x 3mm
defaultMarginTopp = 255; // 720 x 9mm
defaultMarginBottomp = pageSetHeight - 355; // 720 x 9mm
break;
Maybe to
// 12" Paper - Fanfold
pageSetWidth = 5811; // 720 * 8.07"
pageSetHeight = 8640; // 720 * 12"
defaultMarginLeftp = 85; // 720 x 3mm
defaultMarginRightp = pageSetWidth - 85; // 720 x 3mm
defaultMarginTopp = 255; // 720 x 9mm
defaultMarginBottomp = pageSetHeight - 355; // 720 x 9mm
break;