Getting around bar code bleed
Hi all,
We have been printing labels for a company that can be ... difficult
to work with. JUST a little picky. The shipping labels were meeting
spex until a ribbon change on the main Zebra printer needed replacing.
THEN the labels, both shipping and container labels, started becoming
"IMPOSSIBLE to read!" in the words of the person at the other company.
And she was actually more right than wrong. The barcodes WERE difficult
to read, with a lot of bleeding into the white separators. I tried
several different settings from within ReportBuilder AND we changed
ribbons again. No luck.
Soooo, I opted to create the barcodes on the fly and insert them as
pictures, using TppImages. Here's the procedure that does all the work:
procedure TFrmShipping.JvBitBtn1Click(Sender: TObject);
const
zShorterBC = 0.6042; // HEIGHT of the bar codes
zTallerBC = 0.6354;
zThinnerBC = 3.6875; // WIDTH of the bar codes
zWiderBC = 5.4479;
bcPartNoFileName = 'C:\data\bcPartNo.bmp';
bcQtyFileName = 'C:\data\bcQty.bmp';
bcSerialNoFileName = 'C:\data\bcSerialNo.bmp';
var
zDPI : integer;
begin
// Retrieve dpi
zDPI := eDPI.Value; // Dots per inch and this is a GUESS **72**
// Partno
with BC do begin
Code := 'PA1234BC';
BarWidth := eBarWidth.Value;
BarNarrowToWideRatio := eBarNarrowToWideRatio.Value;
BarToSpaceRatio := eBarToSpaceRatio.Value;
Height := trunc(zDPI * zTallerBC);
Width := trunc(zDPI * zThinnerBC);
Savetofile(bcPartNoFileName);
end;
with imagePartNoBarCode do begin
Height := bc.Height;
Width := bc.Width;
Top := 0.4375;
Left := 0.5937;
picture.LoadFromFile(bcPartNoFileName);
end;
// Qty
with BC do begin
Code := 'Q789';
BarWidth := eBarWidth.Value;
BarNarrowToWideRatio := eBarNarrowToWideRatio.Value;
BarToSpaceRatio := eBarToSpaceRatio.Value;
Height := trunc(zDPI * zShorterBC);
Width := trunc(zDPI * zThinnerBC);
Savetofile(bcQtyFileName);
end;
with imageQtyBarCode do begin
Height := bc.Height;
Width := bc.Width;
Top := 1.3333;
Left := 0.5937;
picture.LoadFromFile(bcQtyFileName);
end;
// SerialNumber
with BC do begin
Code := 'S1234567890';
BarWidth := eBarWidth.Value;
BarNarrowToWideRatio := eBarNarrowToWideRatio.Value;
BarToSpaceRatio := eBarToSpaceRatio.Value;
Height := trunc(zDPI * zTallerBC);
Width := trunc(zDPI * zWiderBC);
Savetofile(bcSerialNoFileName);
end;
with imageSerialNoBarCode do begin
Height := bc.Height;
Width := bc.Width;
Top := 2.2187;
Left := 0.5000; // starts about a tenth of an inch further left
picture.LoadFromFile(bcSerialNoFileName);
end;
pipzSAMPLE.print;
end;
From the DFM as an example ...
object imagePartNoBarCode: TppImage
UserName = 'imagePartNoBarCode'
AlignHorizontal = ahLeft
AlignVertical = avTop
MaintainAspectRatio = True
Stretch = True
Transparent = True
Picture.Data = {lots of hex codes}
mmHeight = 16404
mmLeft = 15081
mmTop = 10054
mmWidth = 95779
end
The output doesn't show ANY of the bar code images ... which is JUST a
tad less than I had before. I check the bitmaps in C:\data and all are
faithfully created. Whether I have an image loaded or not in the design
process seems not to matter. So, it appears that my problem is the line:
picture.loadFromFile(bcFileName); // bcFileName replaced by real names
Something is coming acropper in there.
I am using SysTools' TStBarCode for bar code production. The DPI is
producing the model dimensions with 72, so I THINK I've guessed the
dots to inch measurement correctly. The default of barcode width being
12 seemed a little thin in initial tests. A setting there of 18 seemed
to work in filling out the bar code, keeping it within the model
dimensions and producing readable code (in the Delphi 7/RB 12 IDE).
I should also mention that I had to change the Pip's PageLimit to 1. It
did a runaway on the first trial before that.
I'm running out of ideas at this point. I'm producing the bitmaps
successfully. There's not much more for me to do then just import them.
I'm not doing a gazillion of them running into memory limits like
multiple queries might produce. I just get empty spaces.
What AM I doing wrong?
Thanks in advance for your help, GM.
We have been printing labels for a company that can be ... difficult
to work with. JUST a little picky. The shipping labels were meeting
spex until a ribbon change on the main Zebra printer needed replacing.
THEN the labels, both shipping and container labels, started becoming
"IMPOSSIBLE to read!" in the words of the person at the other company.
And she was actually more right than wrong. The barcodes WERE difficult
to read, with a lot of bleeding into the white separators. I tried
several different settings from within ReportBuilder AND we changed
ribbons again. No luck.
Soooo, I opted to create the barcodes on the fly and insert them as
pictures, using TppImages. Here's the procedure that does all the work:
procedure TFrmShipping.JvBitBtn1Click(Sender: TObject);
const
zShorterBC = 0.6042; // HEIGHT of the bar codes
zTallerBC = 0.6354;
zThinnerBC = 3.6875; // WIDTH of the bar codes
zWiderBC = 5.4479;
bcPartNoFileName = 'C:\data\bcPartNo.bmp';
bcQtyFileName = 'C:\data\bcQty.bmp';
bcSerialNoFileName = 'C:\data\bcSerialNo.bmp';
var
zDPI : integer;
begin
// Retrieve dpi
zDPI := eDPI.Value; // Dots per inch and this is a GUESS **72**
// Partno
with BC do begin
Code := 'PA1234BC';
BarWidth := eBarWidth.Value;
BarNarrowToWideRatio := eBarNarrowToWideRatio.Value;
BarToSpaceRatio := eBarToSpaceRatio.Value;
Height := trunc(zDPI * zTallerBC);
Width := trunc(zDPI * zThinnerBC);
Savetofile(bcPartNoFileName);
end;
with imagePartNoBarCode do begin
Height := bc.Height;
Width := bc.Width;
Top := 0.4375;
Left := 0.5937;
picture.LoadFromFile(bcPartNoFileName);
end;
// Qty
with BC do begin
Code := 'Q789';
BarWidth := eBarWidth.Value;
BarNarrowToWideRatio := eBarNarrowToWideRatio.Value;
BarToSpaceRatio := eBarToSpaceRatio.Value;
Height := trunc(zDPI * zShorterBC);
Width := trunc(zDPI * zThinnerBC);
Savetofile(bcQtyFileName);
end;
with imageQtyBarCode do begin
Height := bc.Height;
Width := bc.Width;
Top := 1.3333;
Left := 0.5937;
picture.LoadFromFile(bcQtyFileName);
end;
// SerialNumber
with BC do begin
Code := 'S1234567890';
BarWidth := eBarWidth.Value;
BarNarrowToWideRatio := eBarNarrowToWideRatio.Value;
BarToSpaceRatio := eBarToSpaceRatio.Value;
Height := trunc(zDPI * zTallerBC);
Width := trunc(zDPI * zWiderBC);
Savetofile(bcSerialNoFileName);
end;
with imageSerialNoBarCode do begin
Height := bc.Height;
Width := bc.Width;
Top := 2.2187;
Left := 0.5000; // starts about a tenth of an inch further left
picture.LoadFromFile(bcSerialNoFileName);
end;
pipzSAMPLE.print;
end;
From the DFM as an example ...
object imagePartNoBarCode: TppImage
UserName = 'imagePartNoBarCode'
AlignHorizontal = ahLeft
AlignVertical = avTop
MaintainAspectRatio = True
Stretch = True
Transparent = True
Picture.Data = {lots of hex codes}
mmHeight = 16404
mmLeft = 15081
mmTop = 10054
mmWidth = 95779
end
The output doesn't show ANY of the bar code images ... which is JUST a
tad less than I had before. I check the bitmaps in C:\data and all are
faithfully created. Whether I have an image loaded or not in the design
process seems not to matter. So, it appears that my problem is the line:
picture.loadFromFile(bcFileName); // bcFileName replaced by real names
Something is coming acropper in there.
I am using SysTools' TStBarCode for bar code production. The DPI is
producing the model dimensions with 72, so I THINK I've guessed the
dots to inch measurement correctly. The default of barcode width being
12 seemed a little thin in initial tests. A setting there of 18 seemed
to work in filling out the bar code, keeping it within the model
dimensions and producing readable code (in the Delphi 7/RB 12 IDE).
I should also mention that I had to change the Pip's PageLimit to 1. It
did a runaway on the first trial before that.
I'm running out of ideas at this point. I'm producing the bitmaps
successfully. There's not much more for me to do then just import them.
I'm not doing a gazillion of them running into memory limits like
multiple queries might produce. I just get empty spaces.
What AM I doing wrong?
Thanks in advance for your help, GM.
This discussion has been closed.
Comments
This is likely a conversion issue where the image is either too big or
too small to be seen in the report.
As a test, try setting the TppImage.Stretch property to True and see if
that allows you to view the barcode image. It's best to test this with
an empty report and a minimal Delphi application before moving it to
your main app.
If I understand your first comments correctly, this worked fine using
the RB barcode component until a ribbon was changed in the printer, then
it stopped working? It seems this would be a printer issue rather than
a ReportBuilder one.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico,
As usual, I managed to bury the lede with too much verbiage and
details. Undoubtedly, there is a printer issue. The output has changed
and there is bleeding on labels printed using the ppDBBarCode
component. Why? I don't know. Other customers are not having any issues
reading their labels, but this particular customer has a
non-(ISO)standard label and their scanning equipment probably isn't the
best.
But my job is to create a solution that works. The solution I WANTED
to work was to create the bar code NOT USING ppDBBarCodes, opting to
use the old SysTools components. I then wanted to save them from there
to a disk file, then re-load that file into a ppImage component on the
fly and print. IT WOULD NOT LOAD THE FILE. At least on the run. The
files were being properly created. Indeed, I could load them into the
IDE without issue and see the barcode images. But on the fly? No. The
ppImage1.LoadFromFile('C:\data\ExampleBarcode.bmp'). Failed. Blanko.
I have since created a workaround, using the clipboard and loading
the image from there into a DATABASE in a graphic image field. Then the
image field from there is successfully showing on the label via a
ppDBimage component.
Now, doesn't THAT seem like a lot of work because LoadFromFile failed
so utterly and completely with ppImage? I think so. My one line of code
spun off into one PAGE of code.
The end result is that the persnickity customer is reading the bar
codes well enough to stop making waves. The output on the same printer
that bollixes up the barcode component output with bleeding, prints the
pictures with ALMOST no bleed and I can move on.
But I'd sure like to know why I can't depend on LoadFromFile. And I
am worrying about the barcode components too. If the pictures work and
the barcode components don't, then questions arise. I am using D7 and
RB12, so antiquity is a partial explanation.
GM
The TppImage simply leverages the TPicture.LoadFromFile which is a
Delphi routine. This is exactly how the TPicture works on a form.
In my testing with the latest version of ReportBuilder, placing a
TppImage on an empty report and calling
ppImage1.Picture.LoadFromFile('C:\MyImage.bmp'); before calling
ppReport1.Print; inside a button click functions as expected.
I suggest you try something similar and see if you get different results.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico,
I did do that in my earliest tests. It's why I thought my code in the
original start to this thread would work. Certainly, in the ide, I
could run through the load picture interactive process and the barcode
picture would load without any issues. Come run-time, the process
failed. Rather miserably. Without an error message. Just a big blank
white spot on the screen and on the output.
Where once I wanted to just [1] create the label with SysTools [2] save
the label with .SaveToFile and then [3] ppImage.LoadFromFile, the
sequence now looks like this:
TblIncomingBarCodes.active := false;
TblIncomingBarCodes.EmptyTable;
TblIncomingBarCodes.active := true;
TblIncomingBarCodes.Insert;
TblIncomingBarCodes.FieldByName('PartNum').AsString := 'A1234BC';
...
copyToClipboard;
if Clipboard.HasFormat(CF_BITMAP)
then try
ClipBoard.Open;
MyHandle := Clipboard.GetAsHandle(CF_BITMAP);
iFldOneBC.picture.LoadFromClipboardFormat(CF_BITMAP, MyHandle,
iFldOneBC.Picture.Bitmap.palette);
finally Clipboard.Close;
end;
...
Repeat, Rinse, Wash ...
There's plenty of creating code and all that. The database is an 'on
the fly' thing done using kbmMemtables. The iFldOneBC and so-on fields
are all graphic fields in Paradox file formats. And it's ppDBimage
fields printing those barcode pictures (apparently) successfully now,
rather than the original ppDBbarcode components.
So, recapping:
Used Barcode components and they worked for a period of time until the
printer ribbon was changed. Bleeding occured and continue to do so with
yet ANOTHER new ribbon.
Switched to using a ppImage component and filling it a run time with a
barcode created outside of RB, saved to disk and then loading it to
print. Result: blank space.
Finally created an in-memory database, created the barcode externally
to RB and used the clipboard to fill the Graphic field, followed by
connecting it to a ppDBimage field which successfully printed a
readable bar code.
Using RB12, Delphi 7, SysTools whatever the last version was (I
actually paid for the thing way back when). Take-away from the process?
Well, I learned about using the clipboard, something I've managed to
avoid over the years in anything other than a copy, paste and delete
way for text. And I took the 20-second process of typing in
ppimage1.loadFromFile(bcfilename) and turned it into a week-long
adventure.
Back to you Nico. And honestly, because I know the next reply should
end this thread, you guys down there should have a great Labour Day
weekend. I know this sounds like a complaint, and it is, but I really
do appreciate what RB does for me and what you specifically have done
for me over the years. Enjoy the holiday when it starts.
GM
Thanks for the reply and I'm glad you got it working. It still concerns
me that LoadFromFile is not working for you but if your client is
content, there is likely no reason to pursue this further.
If you would like help digging deeper for this issue in the future, we
would be happy to help.
Have a great Labor Day weekend as well!
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com