I have created a code to print barcode on a barcode printer, but now trying to add to the printing the price for the product which is in a textbox
here is my code
private void frmAddProduct_Load(object sender, EventArgs e)
{
string barcode = txtCode.Text;
Bitmap bitm = new Bitmap(barcode.Length * 40, 110);
using (Graphics graphic = Graphics.FromImage(bitm))
{
Font newfont = new Font("IDAutomationHC39M", 14);
PointF point = new PointF(2f, 2f);
SolidBrush black = new SolidBrush(Color.Black);
SolidBrush white = new SolidBrush(Color.White);
graphic.FillRectangle(white, 0, 0, bitm.Width, bitm.Height);
graphic.DrawString("*" + barcode + "*", newfont, black, point);
}
using (MemoryStream Mmst = new MemoryStream())
{
bitm.Save("ms", ImageFormat.Jpeg);
pictureBox1.Image = bitm;
pictureBox1.Width = bitm.Width;
pictureBox1.Height = bitm.Height;
}
}
private void btnCodePrint_Click(object sender, EventArgs e)
{
short numCopies = 0;
numCopies = Convert.ToInt16(txtCodeNo.Text);
PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new PrinterSettings();
if (DialogResult.OK == pd.ShowDialog(this))
{
PrintDocument pdoc = new PrintDocument();
pdoc.PrintPage += new PrintPageEventHandler(pqr);
pdoc.PrinterSettings.Copies = numCopies;
pdoc.Print();
}
}
that's the issue I'm currently having, I want to add the price from the textbox into the barcode above or under the barcode in the image attached but I can't seem to find a way to make this work, everything I try makes the barcode not work
EDIT
I tried this but showed the price above the barcode
string barcode = txtCode.Text;
string price = txtPprice.Text;
Bitmap bitm = new Bitmap(barcode.Length * 40, 110);
using (Graphics graphic = Graphics.FromImage(bitm))
{
Font newfont = new Font("IDAutomationHC39M", 14);
Font newfont2 = new Font("Arial", 14);
PointF point = new PointF(2f, 2f);
SolidBrush black = new SolidBrush(Color.Black);
SolidBrush white = new SolidBrush(Color.White);
graphic.FillRectangle(white, 0, 0, bitm.Width, bitm.Height);
graphic.DrawString("*" + price + "*", newfont2, black, point);
graphic.DrawString("*" + barcode + "*", newfont, black, point);
This is your problem, point is actually the point where you are drawing the bar-code, and you are using it to draw your price as well. You will need to make a new point, i.e a different coordinate
...
// a new point for your price
PointF pointPrice = new PointF(20f, 20f);
// Draw your price
graphic.DrawString("*" + price + "*", newfont2, black, pointPrice);
// Draw your barcode
graphic.DrawString("*" + barcode + "*", newfont, black, point);
Just play around with the values for pointPrice to figure out the placement position you want
Good luck
Related
In windows application(C#), When draw string using DrawString function of System.Drawing.Graphics class. But values are not properly aligned with other values though X and Y coordinates are the same. It behaves differently for different fonts with different font sizes. I have considered an internal leading and deduct it from Y coordinate but still is not working for all font types.
In my example, I want all text part to be top-aligned with the horizontal line. But for different fonts and font size, It is not aligned properly. It is working for first font(Avenir Black) but not for others.
Below is the code I am using to generate this printed document:
static void PrintDocument(string filePath)
{
// Create new document
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(delegate (Object sender, PrintPageEventArgs e)
{
//e.Graphics.Clear(Color.White);
var Canvas = e.Graphics;
var rectF = new RectangleF(0f, 100, 1000, 78.74016f);
Pen p = new Pen(Color.Black);
p.Width = 1 / 2;
p.DashStyle = DashStyle.Solid;
Canvas.DrawLine(p, rectF.X, rectF.Y, rectF.X + rectF.Width, rectF.Y);
rectF = new RectangleF(0f, 100, 250, 78.74016f);
DrawPrice(Canvas, "Avenir Black", ref rectF);
rectF.X += 20;
rectF.Y = 100;
DrawPrice(Canvas, "Arial", ref rectF);
rectF.X += 20;
rectF.Y = 100;
DrawPrice(Canvas, "Calibri", ref rectF);
rectF.X += 20;
rectF.Y = 100;
DrawPrice(Canvas, "Times New Roman", ref rectF);
});
pd.Print();
Process.Start(filePath);
}
private static void DrawPrice(Graphics Canvas, string fontName, ref RectangleF rectF)
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
var superFont = new Font(fontName, 20, new FontStyle());
var font = new Font(fontName, 61, new FontStyle());
Brush brush = new SolidBrush(Color.FromName("black"));
var currencySymbol = "$";
var mainPrice = "29";
var cents = "50";
var superFontMetrics = FontInfo(Canvas, superFont, GraphicsUnit.Point);
var fontMetrics = FontInfo(Canvas, font, GraphicsUnit.Point);
var symbolSize = Canvas.MeasureString(currencySymbol, superFont, rectF.Size, format);
var centsSize = Canvas.MeasureString(cents, superFont, rectF.Size, format);
var dollarSize = Canvas.MeasureString(mainPrice, font, rectF.Size, format);
Canvas.DrawString(currencySymbol, superFont, brush, new RectangleF(rectF.X, rectF.Y - superFontMetrics.InternalLeading, symbolSize.Width, symbolSize.Height), format);
rectF.X += symbolSize.Width;
Canvas.DrawString(mainPrice, font, brush, new RectangleF(rectF.X, rectF.Y, dollarSize.Width, rectF.Height), format);
var mainPriceX = rectF.X + (dollarSize.Width / 2);
rectF.X += dollarSize.Width;
Canvas.DrawString(cents, superFont, brush, new RectangleF(rectF.X, rectF.Y - superFontMetrics.InternalLeading, centsSize.Width, centsSize.Height), format);
rectF.Y += rectF.Height;
rectF.X += centsSize.Width;
var titleFont = new Font(fontName, 5, new FontStyle());
var titleTextSize = Canvas.MeasureString(fontName, titleFont, rectF.Size, format);
Canvas.DrawString(fontName, titleFont, brush, new RectangleF(mainPriceX, rectF.Y, titleTextSize.Width, titleTextSize.Height), format);
}
public static FontMetrics FontInfo(Graphics gr, Font font, GraphicsUnit toUnit)
{
FontMetrics metrics = new FontMetrics();
float em_height = font.FontFamily.GetEmHeight(font.Style);
metrics.EmHeight = ConvertUnits(gr, font.Size, font.Unit, toUnit);
float design_to_points = metrics.EmHeight / em_height;
metrics.Ascent = design_to_points * font.FontFamily.GetCellAscent(font.Style);
metrics.Descent = design_to_points * font.FontFamily.GetCellDescent(font.Style);
metrics.CellHeight = metrics.Ascent + metrics.Descent;
metrics.InternalLeading = metrics.CellHeight - metrics.EmHeight;
metrics.LineSpacing = design_to_points * font.FontFamily.GetLineSpacing(font.Style);
metrics.ExternalLeading = metrics.LineSpacing - metrics.CellHeight;
return metrics;
}
After using GraphicsPath >> AddString method to print string, I got the result I want i.e. printed texts are top aligned for all type of fonts. Here is the output:
Below is the code I used:
private void DrawStringByGraphicsPath(Graphics g, Font font, Brush brush, ref RectangleF rectF, RectangleF elementRectF, StringFormat format, string text)
{
if (!string.IsNullOrEmpty(text))
{
using (GraphicsPath graphicsPath = new GraphicsPath())
{
graphicsPath.AddString(text, font.FontFamily, (int)font.Style, GetEMSize(g, font), elementRectF.Location, format);
// this is the net bounds without any whitespace:
RectangleF br = graphicsPath.GetBounds();
// Transform it for top alignment
g.TranslateTransform(elementRectF.X - br.X, (elementRectF.Y - br.Y));
g.FillPath(brush, graphicsPath);
g.ResetTransform();
}
}
}
private float GetEMSize(Graphics canvas, Font font)
{
return (font.SizeInPoints * (font.FontFamily.GetCellAscent(font.Style) + font.FontFamily.GetCellDescent(font.Style))) / font.FontFamily.GetEmHeight(font.Style);
}
I 'm using the code below to print the barcode that gets generated in my C# WinForms, but the barcode scanner does not detect it, I've tried using code 128 font and code39 fonts with no luck, when I print using the bartender software it detects the barcode generated, just won't detect mine
here is the code
private void txtPprice_TextChanged(object sender, EventArgs e)
{
string barcode = txtCode.Text;
string price = txtPprice.Text;
string pname = txtPname.Text;
Bitmap bitm = new Bitmap(barcode.Length * 30, 90);
using (Graphics graphic = Graphics.FromImage(bitm))
{
Font newfont = new Font("IDAutomationHC39M", 10);
Font newfont2 = new Font("Arial Black", 8);
PointF point = new PointF(10f, 10f);
SolidBrush black = new SolidBrush(Color.Black);
SolidBrush white = new SolidBrush(Color.White);
graphic.FillRectangle(white, 0, 0, bitm.Width, bitm.Height);
graphic.DrawString("*" + barcode + "*", newfont, black, point);
PointF pointPrice = new PointF(45f, 55f);
graphic.DrawString("" + pname +"", newfont2, black, pointPrice);
PointF pointPname = new PointF(90f, 75f);
graphic.DrawString("" + price + " L.E.", newfont2, black, pointPname);
PointF pointBcode = new PointF(20f, 75f);
graphic.DrawString("" + barcode + "", newfont2, black, pointBcode);
}
using (MemoryStream Mmst = new MemoryStream())
{
bitm.Save("ms", ImageFormat.Jpeg);
pictureBox1.Image = bitm;
pictureBox1.Width = bitm.Width;
pictureBox1.Height = bitm.Height;
}
}
I have tried adding and removing the * as suggested in other posts, also changing the font size from 8p went one by one till 28px, but still no luck
the scanner and the printer are working fine on the bartender application
The code used in the example below is 5094411
Here is an image, the textbox highlighted in red is where the string barcode is coming from
and you can see in the image that in the picturebox it shows 5094411 in both IDautomationHC39M font (the barcode font) and again below it in Arial
This is the correct code that after some tries with the help of Jimi here I was able to get this part right
string Barcode = "*"+txtCode.Text+"*";
string price = txtPprice.Text;
string pname = txtPname.Text;
using (Bitmap bitmap = new Bitmap(350, 220))
{
bitmap.SetResolution(240, 240);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
Font font = new Font("IDAutomationHC39M", 10, FontStyle.Regular, GraphicsUnit.Point);
graphics.Clear(Color.White);
StringFormat stringformat = new StringFormat(StringFormatFlags.NoWrap);
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
graphics.TextContrast = 10;
SolidBrush black = new SolidBrush(Color.Black);
SolidBrush white = new SolidBrush(Color.White);
PointF TextPosition = new PointF(45F, 10F);
SizeF TextSize = graphics.MeasureString(Barcode, font, TextPosition, stringformat);
PointF pointPrice = new PointF(90f, 125f);
Font newfont2 = new Font("Cambria", 8, FontStyle.Regular, GraphicsUnit.Point);
Font newfont3 = new Font("Arial Black", 10, FontStyle.Regular, GraphicsUnit.Point);
graphics.DrawString("" + pname + "", newfont3, black, pointPrice);
PointF pointPname = new PointF(200f, 170f);
graphics.DrawString("" + price + " L.E.", newfont3, black, pointPname);
PointF pointBcode = new PointF(35f, 170f);
graphics.DrawString("" + Barcode + "", newfont2, black, pointBcode);
if (TextSize.Width > bitmap.Width)
{
float ScaleFactor = (bitmap.Width - (TextPosition.X / 2)) / TextSize.Width;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.ScaleTransform(ScaleFactor, ScaleFactor);
}
graphics.DrawString(Barcode, font, new SolidBrush(Color.Black), TextPosition, StringFormat.GenericTypographic);
bitmap.Save(#"barcode.png", ImageFormat.Png);
this.pictureBox1.Image = (Bitmap)bitmap.Clone();
font.Dispose();
}
}
I have made an application which generates me a QR Code in a PNG image, but now I have to insert the text from QR Code next to the QR Code image.
I don't have any experience using ZXing Library but I'm thinking that it may contain an option for this...
Example:
Code:
namespace QR_Code_with_WFA
{
public void CreateQRImage(string inputData)
{
if (inputData.Trim() == String.Empty)
{
System.Windows.Forms.MessageBox.Show("Data must not be empty.");
}
BarcodeWriter qrcoder = new ZXing.BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new ZXing.QrCode.QrCodeEncodingOptions
{
ErrorCorrection = ZXing.QrCode.Internal.ErrorCorrectionLevel.H,
Height = 250,
Width = 250
}
};
string tempFileName = System.IO.Path.GetTempPath() + inputData + ".png";
Image image;
String data = inputData;
var result = qrcoder.Write(inputData);
image = new Bitmap(result);
image.Save(tempFileName);
System.Diagnostics.Process.Start(tempFileName);
}
}
Well, ZXing.BarcodeWriter.Options has property PureBarcode, which will put source text into generated image when set to false.
Unfortunately it has no effect when format of barcode is BarcodeFormat.QR_CODE (and it is by design).
But you can draw your text manually after you've generated barcode image:
var result = qrcoder.Write(inputData);
using (var g = Graphics.FromImage(result))
using (var font = new Font(FontFamily.GenericMonospace, 12))
using (var brush = new SolidBrush(Color.Black))
using(var format = new StringFormat(){Alignment = StringAlignment.Center})
{
int margin = 5, textHeight = 20;
var rect = new RectangleF(margin, result.Height - textHeight,
result.Width - 2 * margin, textHeight);
g.DrawString(inputData, font, brush, rect, format);
}
result.Save(tempFileName);
Note you can select your own font size and fontfamily which will better suite your goals.
Update:
In the case you're trying to place text to the right from image - you have to "extend" to the right your generated image first, and then draw text:
var result = qrcoder.Write(inputData);
int textWidth = 200, textHeight = 20;
// creating new bitmap having imcreased width
var img = new Bitmap(result.Width + textWidth, result.Height);
using (var g = Graphics.FromImage(img))
using (var font = new Font(FontFamily.GenericMonospace, 12))
using (var brush = new SolidBrush(Color.Black))
using (var bgBrush = new SolidBrush(Color.White))
using (var format = new StringFormat() { Alignment = StringAlignment.Near })
{
// filling background with white color
g.FillRectangle(bgBrush, 0, 0, img.Width, img.Height);
// drawing your generated image over new one
g.DrawImage(result, new Point(0,0));
// drawing text
g.DrawString(inputData, font, brush, result.Width, (result.Height - textHeight) / 2, format);
}
img.Save(tempFileName);
I have two List one is of string and the other is of PictureBox type. I want to take the values of List of type string and the convert it into the Barcode then save it to the List of type PictureBox.
I am doing it like this right now:
List<System.Windows.Forms.PictureBox> PictureBoxList = new List<System.Windows.Forms.PictureBox>();
List<string> SerialNumberList = new List<string>();
int SerialNumberStart = 0;
for(int i = 0; i < 10 ; i++)
{
SerialNumberStart++;
SerialNumberList.Add("S" + SerialNumberStart);
}
private void PrintButton_Click(object sender, EventArgs e)
{
for(int j =0 ; j < SerialNumberList.Count ; j++)
{
BarcodeLib.TYPE barcodetype1 = BarcodeLib.TYPE.CODE39;
BarcodeLib.Barcode bar1 = new BarcodeLib.Barcode();
bar1.IncludeLabel = true;
PictureBoxList[j].Image = bar1.Encode(barcodetype1 ,SerialNumberList[j]); // It gives me exception of Index out of range
PictureBoxList.Add(PictureBoxList[j]);
printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage);
printDocument1.Print();
}
}
private void PrintDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Bitmap myBitmap1 = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.DrawToBitmap(myBitmap1, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
e.Graphics.DrawImage(myBitmap1, 0, 0);
myBitmap1.Dispose();
}
My first question is that How can I convert the string into the PictureBox.
And then converting each item of the PictureBox to the Bitmap and then printing all of the bitmaps now the code only Prints one barcode
you want like this.. right?? see this is the representaion of the this string "S1253551" in 3of9 and plain text and finally as image right??
public Image stringToImage(string inputString)
{
string text = inputString.Trim();
Bitmap bmp = new Bitmap(1, 1);
//Set the font style of output image
Font font = new Font("Free 3 of 9", 25, FontStyle.Regular, GraphicsUnit.Pixel);
Font font2 = new Font("Arial", 15, FontStyle.Regular, GraphicsUnit.Pixel);
Graphics graphics = Graphics.FromImage(bmp);
int width = (int)graphics.MeasureString(text, font).Width;
int height = (int)graphics.MeasureString(text, font).Height;
int height2 = (int)graphics.MeasureString(text, font2).Height;
bmp = new Bitmap(bmp, new Size(width, height+height2));
graphics = Graphics.FromImage(bmp);
//Specify the background color of the image
graphics.Clear(Color.Cyan);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
//Specify the text, font, Text Color, X position and Y position of the image
graphics.DrawString(text, font, new SolidBrush(Color.Black), 0, 0);
graphics.DrawString(text, font2, new SolidBrush(Color.Black), 0, height);
graphics.Flush();
graphics.Dispose();
//if you want to save the image uncomment the below line.
//bmp.Save(#"d:\myimage.jpg", ImageFormat.Jpeg);
return bmp;
}
Remember you must have installed "free 3 of 9" font.
you pass the string "S1253551" and it generate the barcode and add the plain text at bottom and finally return it as image.
Its working code i have tried at my end. Enjoy. :)
Download the working code from here Download
mean you have string and you have converted it to barcode. finally we have a property in barcode which holds the value of string right?? now you want to display that string as image??
if so then refer the below code -
public Image stringToImage(string inputString)
{
string text = inputString.Trim();
Bitmap bmp = new Bitmap(1, 1);
//Set the font style of output image
Font font = new Font("Arial", 25, FontStyle.Regular, GraphicsUnit.Pixel);
Graphics graphics = Graphics.FromImage(bmp);
int width = (int)graphics.MeasureString(text, font).Width;
int height = (int)graphics.MeasureString(text, font).Height;
bmp = new Bitmap(bmp, new Size(width, height));
graphics = Graphics.FromImage(bmp);
//Specify the background color of the image
graphics.Clear(Color.Cyan);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
//Specify the text, font, Text Color, X position and Y position of the image
graphics.DrawString(text, font, new SolidBrush(Color.Black), 0, 0);
graphics.Flush();
graphics.Dispose();
//if you want to save the image uncomment the below line.
//bmp.Save(#"d:\myimage.jpg", ImageFormat.Jpeg);
return bmp;
}
I believe, if bar1.Encode actually has return type of Image, this lines in PrintButton_Click method :
PictureBoxList[j].Image = bar1.Encode(barcodetype1 ,SerialNumberList[j]); // It gives me exception of Index out of range
PictureBoxList.Add(PictureBoxList[j]);
should be like this :
var pictureBox = new PictureBox();
pictureBox.Image = bar1.Encode(barcodetype1 ,SerialNumberList[j]);
PictureBoxList.Add(pictureBox);
UPDATE :
To make it clear, my answer above meant PrintButton_Click should be as follow :
private void PrintButton_Click(object sender, EventArgs e)
{
for(int j =0 ; j < SerialNumberList.Count ; j++)
{
BarcodeLib.TYPE barcodetype1 = BarcodeLib.TYPE.CODE39;
BarcodeLib.Barcode bar1 = new BarcodeLib.Barcode();
bar1.IncludeLabel = true;
var pictureBox = new PictureBox();
pictureBox.Image = bar1.Encode(barcodetype1 ,SerialNumberList[j]);
PictureBoxList.Add(pictureBox);
printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage);
printDocument1.Print();
}
}
My code:
private void CreateAnimatedGif(List<string> GifsFilesRadar , List<string> GifsFilesSatellite)//string FileName1 , string FileName2)
{
Bitmap bitmap = null;
DirectoryInfo inf = new DirectoryInfo(tempGifFiles);
FileInfo[] fi = inf.GetFiles("*.gif");
for (int i = 0; i < fi.Length; i++)
{
Bitmap file1 = new Bitmap(GifsFilesRadar[i]);
Bitmap file2 = new Bitmap(GifsFilesSatellite[i]);
//calculate the new width proportionally to the new height it will have
int newWidth = file1.Width + file1.Width / (file2.Height / (file2.Height - file1.Height));
bitmap = new Bitmap(newWidth + file2.Width, Math.Max(file1.Height, file2.Height));
using (Graphics g = Graphics.FromImage(bitmap))
{
//high quality rendering and interpolation mode
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
//resize the left image
g.DrawImage(file1, new Rectangle(0, 0, newWidth, file2.Height));
g.DrawImage(file2, newWidth, 0);
string t = #"d:\GifsForAnimations" + "\\" + i.ToString("D6") + ".Gif";
bitmap.Save(t, System.Drawing.Imaging.ImageFormat.Gif);
if (i == 4)
{
break;
}
}
}
List<string> gif = new List<string>();
DirectoryInfo info = new DirectoryInfo(#"d:\GifsForAnimations");
FileInfo[] finfo = info.GetFiles();
for (int i = 0; i < finfo.Length; i++)
{
gif.Add(finfo[i].FullName);
}
newFile.MakeGIF(gif, #"d:\newGifAnim.gif", 80, true);
}
In the end I have new animated gif file.
Now I have the border and these are the locations:
Bottom left corner: 232.0,408.0
Top left corner: 232.0,211.0
Top right corner: 524.0,211.0
Bottom right corner: 524.0,408.0
I want to add on each image a frame around it to mark the border around. Let's say the border will be in Red and the border line size will be 5 pixels.
How can I create the rectangle around existing bitmap or gif file ?
It doesn't have to be connected to my example code here but how do I create the frame/border around the image with the locations I have ?
You could add this line after g.DrawImage(file2, newWidth, 0);
g.DrawRectangle(new Pen(Brushes.Red, 5), new Rectangle(0, 0, newWidth, file2.Height));
Here is a small test method so you can see it working
private void button1_Click(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap(#"C:\avatar63.jpg");
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawRectangle(new Pen(Brushes.Red, 5), new Rectangle(0, 0, bitmap.Width, bitmap.Height));
}
bitmap.Save(#"C:\avatar63New.jpg");
}
Before: After:
You can add the rectagle anywhere you want, tou jst need to supply the X,Y,Width,Height
g.DrawRectangle(new Pen(Brushes.LimeGreen, 5), new Rectangle(50, 50, 100, 100));
Using your 4 point structure this should work
Point topLeft = new Point(232,211 );
Point topRightr = new Point(232, 408);
Point bottomLeft = new Point(524, 211);
Point bottomRight = new Point(524, 408);
g.DrawRectangle(new Pen(Brushes.LimeGreen, 5), new Rectangle(topLeft, new Size(topRightr.X - topLeft.X, bottomLeft.Y - topLeft.Y)));
// TopLeft = rectangle location
// TopRight.X - TopLeft.X = Width of rectangle
// BottomLeft.Y - TopLeft.Y = height of rectangle