A client asked me to build an inventory solution for them where they'd print barcode labels for all office equipment to keep track of them in various ways.
They gave me a Citizen CL-S621 printer (203x203 dpi resolution) to use for testing and after (the nightmare that was) configuring its drivers to print and fitting everything to the nonstandard labels they gave me to test, the biggest problem I'm still running into is that the printer is having trouble printing some bars in a straight line and instead prints them in dashed/dotted forms.
The C# Code below shows the basics of how I build the barcodes using this library :
public void CreateTheBarcode(string StringToEncode)
{
Barcode b = new Barcode();
b.LabelFont = new Font("Sample Bar Code Font", 24, FontStyle.Bold);
b.IncludeLabel = true;
b.Encode(BarcodeLib.TYPE.CODE128, StringToEncode, Color.Black, Color.White, 730, 140);
b.SaveImage(#"C:\temp\Barcodes\"+StringToEncode+".png",SaveTypes.PNG);
Print(#"C:\temp\Barcodes\"+StringToEncode+".png");
}
public static void Print(string FilePath)
{
Process printJob = new Process();
printJob.StartInfo.FileName = FilePath;
printJob.StartInfo.UseShellExecute = true;
printJob.StartInfo.Verb = "printto";
printJob.StartInfo.CreateNoWindow = false;
printJob.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
printJob.StartInfo.Arguments = "\"" + "Citizen CL-S621" + "\"";
printJob.StartInfo.WorkingDirectory = Path.GetDirectoryName(FilePath);
printJob.Start();
}
The hardcoded width and height are the best approximation I found of a good image size the printer would accept and accurately print onto the labels since I had to measure their size by ruler and between printer offsets and eye-measurement accuracy issues getting a size that worked proved troublesome.
In any case, I generated some barcodes and the images are crisp, clear and seem pretty good:
The lines are straight and clearly defined, the text is sharp, everything seems fine;
but when I go to print them I get:
Some of the bars print straight and clear while some have irregular edges and some are just irregular dot/slash/curved patterns. The text in all of them suffers the same issue. I have tried different font sizes and supposedly barcode-friendly fonts and the issue persists. The problem persists if I remove the text labels.
It strikes me as an image rasterization issue but I am not fully sure, nor do I know how to fix that.
I'm not yet sure if a scanner can read these or not, I receive one tomorrow, but any tips on what I may be doing wrong would be appreciated.
These printer settings should help:
Select the printer in Device and Printers > Printing Preferences > Graphics
Set Dithering to None
The printer is antialiasing your images. This is an endemic problem with barcode fonts. You have to either set your printer to not antialias (try Settings/Printer/Printing Preferences/Color Mode/Monochrome) or you have to set the image DPI to be identical to the printer DPI (typically 300 DPI).
If your printer renders to a rectangle and not to a DPI, you have to size your image so the image pixels are an integer multiple of the printer pixels of the same rectangle.
It's difficult to propose a solution to your problem because you have too many moving parts; you start with a font that goes to an image that goes to a file that goes to a shell command that goes to an application you haven't told us about that goes to a printer. Any one of those steps could anti-alias your image.
My suggestion is to remove these intermediate parts. What's calling CreateTheBarcode? An application you wrote? Try having that application print to the printer directly using .NET System.Drawing.Printing.PrintDocument. You can't do that and have to use the mystery application UseShellExecute calls? Study that application, maybe there is some way you can send printer commands instead of going through all that font to image to file rigamarole; many label printers have ways to output text like “test 123” directly as barcodes.
Edit: Maybe what you are attempting is flat-out impossible. What are the dimensions of the label you are printing to? Your “More numbers” example is over 500 px across and your printer is only 200 DPI. If the labels are narrower than 500/200 ≅ 2.5 inches there is no way the bars will fit even if you print at 203 DPI.
Same problem and this worked perfectly.
Option 1: Adjust Dithering Settings
Click the Windows button.
Go to Control Panel.
Go to Devices and Printers.
Right-click preferred printer.
Click "Printer Preferences".
Go to "Dithering" tab and select "None".
Click apply.
Related
I am trying to use PrintDocument and set up the paper size to print or barcode thermal printer. Because I don't have the printer nearby I am using Microsoft Print To PDF option which appeared in Win10.
During initialization I have such code:
As you see, here I am trying to set up custom paper size for default paper size. But, I cannot specify Kind property, because it's readonly! RawKind property not helps.
As alternative I have such event. It does not help either. It correctly displays the page layout on preview, but in PDF document I observe pages printed in A4, as by default.
private void PrintDoc_QueryPageSettings(object sender, QueryPageSettingsEventArgs e)
{
PageSettings nSettings = new PageSettings();
int properWidthInHundretsOfInches = (int)(handlingClassRef.newconfig.labelParameters.barcodeLabelWidthMM * (1.0 / 25.4) * 100.0);
int properHeightInHundretsOfInches = (int)(handlingClassRef.newconfig.labelParameters.barcodeLabelHeightMM * (1.0 / 25.4) * 100.0);
nSettings.PaperSize = new PaperSize("label", (int)properWidthInHundretsOfInches, (int)properHeightInHundretsOfInches);
e.PageSettings = nSettings;
}
I am aware of question How to print with custom paper size in winforms , but I don't actually understand the answer. Should I reconfigure printer by using printer properties OS dialog? I would like rather not to require user to modify settings of of printer in one way or another. Also, I'd like to achieve appropriate result during printing to pdf exploration phase.
How to set up and print with custom paper size in C# printdocument?
Edit: using the line:
printDoc.DefaultPageSettings.PaperSize = new PaperSize("label", properWidthInHundretsOfInches, properHeightInHundretsOfInches);
did not resolve question.
Here is a result:
preview is nice and small but printed document is large and has not proper page size
You can try by initialising PaperSize class under System.Drawing.Printing and then you can specify the custom size
printDoc.DefaultPageSettings.PaperSize = new PaperSize("MyPaper", 600, 800);
I found the solution for this!
The Short Answer is :
printDocument1.DefaultPageSettings.PaperSize = new PaperSize("MyPaper", 700, 900);
Why it's printing A4 Paper Size, Not Full Report?
Because The Default Virtual pdf printer in Windows Microsoft Print To Pdf uses A4 Paper Size, you can try to change it to A5 from the Control Panel And try to print it again. You will notice that it has included more lines on the pdf output!
So don't worry, the code I have mentioned is Correct, but it depends on the printer you use. Because printers Use only Some Formatted Paper Sizes and it will not accept more pages out of the frame.
See This picture for more explanation
..
First, I was furious Because of this problem,
I thought that printpreviewDialog1 had another Printable area, and I tried to make it as exact as printdocument1, and then I noticed it's just a viewer.
After hours of research and many tries, I noticed that the printer wouldn't accept Any more lines; I was working on a Cashier report. I needed to make a long paper for the thermal printer, but when I was testing on the "print to pdf" printer, it didn't Print all the lines on preview control because it just prints to A4 size, mo more and no less!
I have a RadRichTextBox that have a RadDocument loaded. This is then used to print mentioned document using richTextBox.Print().
The main problem is that the resolution of the printed page is tied to the zoom of the document in the viewer (RadRichTextBox), i.e. if I have the document zoomed way out (small pages on screen) the resolution on the printed paper is terrible. On the other hand, if I zoom in, the resolution becomes really good.
Obviously, I want to always print at the best possible resolution, is there a way to achieve this?
In the end I went with a work around that works by saving the scaling, setting it to a high number, then restoring it after printing the document.
Size sf = richTextBox.ScaleFactor;
richTextBox.ScaleFactor = new Size(10,10);
richTextBox.Print(/*... settings ...*/);
richTextBox.ScaleFactor = sf;
This looks weird, as the documents zooms in while the document is printing, but the printed document have a proper resolution.
I am working on a windows desktop application that will be used in various resolutions and text sizes. Before getting to AutoScaling and other ways for the desktop application to work, I need to see what the user sees.
Adjusting the resolution of my development machine is not good enough. The biggest kicker is the text size. Some users have it set to 125% of default which distorts practically everything.
Free tools like this only lets you play with resolutions, not text sizes.
Changing the text size in windows 10 is an ordeal, jumping through a lot of hoops. You have to log off and log back in. Also, when I open the project in Visual Studio with the text size change, the forms are jacked up. The form size is shrunk with all the controls outside.
I'm not 100% sure what your asking about but i think this might help you
yourForm.AutoScaleMode = AutoScaleMode.Dpi;
Also here is more info on Scaling in Windows Forms: https://msdn.microsoft.com/en-us/library/ms229605.aspx
Or more info on writing DPI aware Win32 Applications: https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx
You can get the user windows display text size by making a new graphics object
Example:
Graphics graphics = this.CreateGraphics();
flaot windowsFontSize = graphics.DpiX;
string fontSize = string.Empty;
if(windowsFontSize == 96f)
fontSize = "Smaller";
else if (windowsFontSize == 120f)
fontSize = "Medium";
else if (windowsFontSize == 144f)
fontSize = "Larger";
Info found here: How to get Windows Display settings?
The only way to have the program run at 125% text scale without changing you text size in your settings or multiplying everything in your form by 125% is to run a virtual machine. I can personally vouch for Parallels and VMware. If you want to learn more about Virtual Machines you can read this: https://en.wikipedia.org/wiki/Virtual_machine
Problem:
We need help with how to use WinForms' ability to auto-scale to different DPI’s to allow us to print our Forms at 600dpi, rather than at the screen DPI.
For What-You-See-Is-What-You-Get printing, we have been simply taking our nicely laid out window and printing it (turning off scrollbars and buttons and such). That works great EXCEPT for one thing: it comes out at 96dpi or 120dpi (whatever is the screen resolution)… either of which look grainy and unprofessional (our customers are complaining). And although it is as readable as what would be on the screen, you expect printed documents to be MORE readable than on-screen… you expect to be able to see additional details, to be able to read smaller text, etc.
Alternatives considered:
Given we have auto-scaling working great, such that our window looks good in 96dpi, 120dpi, 144 dpi, etc., we were hoping we could just draw our window at 600dpi and then print that.
OR, we looked at drawing the window off-screen 5-6x larger than normal such that we have the same number of pixels as 600dpi, but at 96 or 120 dpi… but then drawing that giant window to the printed page at 300 or 600 dpi (whatever the printer is).
If you can tell us how to do either of those alternatives, OR if you can give us a different way to accomplish our goal, then we would greatly appreciate it.
Current code:
In case it matters, our Form consists of a FlowLayoutPanel laying other smaller FlowLayoutPanels into columns, those smaller FlowLayoutPanels laying out a single column of TextBoxes, RichTextBoxes, a third-party RichTextEditor, PictureBoxes, and DataGridViews. We use a class derived from PrintDocument implementing OnBeginPrint, OnPrintPage, and OnEndPrint. In OnPrintPage, it manipulates our normal window off-screen (below and right of the actual screens) to fit the page size, then asks our main panel (the top FlowLayoutPanel) to DrawToBitmap, then uses the Graphics object passed into the PrintEventArgs to DrawImage that Bitmap. We also use Graphics.DrawString to apply a footer to each page. The main code:
using (Bitmap bm = new Bitmap(sz.Width, sz.Height))
{
Rectangle rect = new Rectangle(0, 0, sz.Width, sz.Height);
mp.DrawToBitmap(bm, rect);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; // so footer is anti-aliased
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // so when we scale up, we smooth out the jaggies somewhat
e.Graphics.DrawImage(bm, this.MarginBounds, rect, GraphicsUnit.Pixel);
if (this.Footer != null)
e.Graphics.DrawImage(this.Footer, this.FooterLocation);
if (!string.IsNullOrEmpty(pageNumber))
{
e.Graphics.DrawString(pageNumber, KBStyle.Normal.Font, Brushes.Black,
this.MarginBounds.X, this.FooterLocation.Y + FooterOffset);
}
}
How should we do this to get 600dpi to the printed page? (Or even 300 dpi would be great!)
When we print this, it looks far better when printed from a 120dpi machine than when printed from a 96dpi machine, hence why we know it is printing at screen resolution. But also makes us wonder if there’s some simple way to tell it “this Form should draw at 600 dpi” and then all the rest of the code above just works.
Note: if we grab an EMF (Enhanced Metafile) and print it to the printer in the code above, that EMF comes out at 600dpi. Unfortunately, we haven’t found a DrawToEMF method that we can call on the FlowLayoutPanel instead of DrawToBitmap. Changing the Bitmap to be 600dpi doesn’t help… the DrawToBitmap method still seems to draw the bitmap at screen resolution.
Thanks!!
Okay, I have figured this out... and it works great!
I still don’t know how to create a form at 300dpi and use the auto-scaling functionality.
BUT…
I have proven that if you create the window 3.125x larger than needed at 96 dpi, and scale the font up 3.125x, and so on, such that everything is the pixel count you’d need to be at 300dpi, even though your screen is at 96dpi, then you can use the normal Control.DrawToBitmap() functionality to turn that into a Bitmap, and then you can use the GDI Graphics.DrawImage(thatGiantBitmap, giantSrcRect, pageSizeDestRect) to the printer Graphics object, and it will map those giant 96dpi pixels to the page-size 300dpi pixels, giving you a 300dpi print. Perfect.
For any of our windows that support resizing AND let our users zoom the contents arbitrarily, then printing What-You-See-Is-What-You-Get is easy:
In OnBeginPrint of your PrintDocument, do:
(1) Optionally dup the Form so as to not mess with what the user is looking at
(2) Move the Form you want to print off-screen (below and right of all your screens)
(3) Set the Form so that it is allowed to grow bigger than the screen size (by default WinForms won’t grow larger than the screen)
(4) Divide 300 dpi by your screen dpi to get the growth factor
(5) Grow your Form by growth factor
(6) Zoom its contents by growth factor (if they don’t auto-scale / auto-zoom with the Form’s size)
In OnPrintPage of your PrintDocument, do:
(7) On whatever Control in your Form you want to print, do DrawToBitmap() to a Bitmap the size of that Control
(8) On the e.Graphics do DrawImage(thatGiantBitmap, giantSrcRect, pageSizeDestRect)
That DrawImage call will draw at the printer’s resolution, if you have that many pixels in your thatGiantBitmap. In this case, I computed the Bitmap to give the number of pixels needed for 300 dpi, so I will get 300 dpi print-outs even if the printer is 600 dpi. If you need full 600 dpi, just use 600 dpi in step 4's calculation.
Total guess here, but what about using CSS? I'm guessing at how much you want to scale, and don't know how you would know what scale the printer is.
Using the print media query makes this work for print but leaves the screen view alone.
#media print {
* {
transform: scale(2000px,2000px);
}
}
I have an application that scan Images from scanner but some scanners put a black border around the saved image.
How can I remove that black border?
Thanks so much for your participation.
I’ve had good luck in the past process images using the Magick.NET library. It’s available on Codeplex or you can install it using NuGet in Visual Studio. Documentation for the library is a little sparse, but it’s served me well in the past.
Depending upon the exact nature of the images you’re dealing with, you might be able to do something as simple as crop off the edges where the border is and then add a white (or whatever color; I just assumed that you were scanning text documents or something) border to bring the image back up to a standardized size. If having a standardized size doesn’t matter, then of course you can just leave the image cropped. If that sounds like a viable solution, here’s some code that should accomplish what you need:
using (MagickImage image = new MagickImage(#"path_to_original"))
{
int width = image.Width, height = image.Height;
image.Crop(width - 800, height - 800);
//if the image needs to be brought back up to a standarized size
image.BorderColor = new ColorRGB(System.Drawing.Color.White);
image.Border(100, 100);
image.Write(#"path_to_cropped_image_with_no_more_black_border_around_it");
}
You will, of course need to add your own values for just how much width you need to crop off/add back in.