I have a webapp that generates a barcode:
protected void btnGenerate_Click(object sender, EventArgs e)
{
string barCode = Barcode + txtCode.Text;
System.Web.UI.WebControls.Image imgBarCode = new System.Web.UI.WebControls.Image();
using (Bitmap bitMap = new Bitmap(barCode.Length * 50, 90))
{
using (Graphics graphics = Graphics.FromImage(bitMap))
{
Font oFont = new Font("IDAutomationHC39M", 18);
PointF point = new PointF(3f, 3f);
SolidBrush blackBrush = new SolidBrush(Color.Black);
SolidBrush whiteBrush = new SolidBrush(Color.White);
graphics.FillRectangle(whiteBrush, 0, 0, bitMap.Width, bitMap.Height);
graphics.DrawString(barCode, oFont, blackBrush, point);
}
using (MemoryStream ms = new MemoryStream())
{
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] byteImage = ms.ToArray();
Convert.ToBase64String(byteImage);
imgBarCode.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteImage);
}
plBarCode.Controls.Add(imgBarCode);
}
It generates the barcodes on the same page, what I was hoping to do, is once the button is pressed it displays the results in a new webpage.
I created a session
Session.Add("BarCodes", plBarCode);
Response.Redirect("barcodes.aspx);
And then on the barcordes.aspx pages"
protected void Page_Load(object sender, EventArgs e)
{
plbcode = (PlaceHolder)Session["Barcodes"];
}
That is incorrect since nothing shows up, but I don't know what else to try. I know I cannot use imgBarCode since it will be throw an exception of an Invalid Cast.
Keeping WebControl in Session is not a good idea. Better way is to move barcode image generation code to second page and pass all necessary params via querystring:
imgBarCode.ImageUrl = "barcodes.aspx?text=foobar&barcode=12345...";
Second page generates an image and writes it directly to Output stream, with image/png content type, without any html markup. Only image data.
Related
I have this code for generating barcode when page is loaded.(code below) txtBarcodeBlack.Text content is pulled from SQL Server Database as varchar.
I have a button submit that will do another process like saving the txtBarcodeBlack.text to database. My problem is when I press the button, it gives me this Problem please help. I'm stuck for 2 days.
private void loadBlackBarcode() {
//barcode black
//txtBarcodeBlack.Text = vBarcodeBlack;
string barCodeBlack = txtBarcodeBlack.Text;
System.Web.UI.WebControls.Image imgBarCodeBlack = new System.Web.UI.WebControls.Image();
using (Bitmap bitMap = new Bitmap(barCodeBlack.Length * 40, 80))
{
using (Graphics graphics = Graphics.FromImage(bitMap))
{
Font oFont = new Font("IDAutomationHC39M", 16);
PointF point = new PointF(2f, 2f);
SolidBrush blackBrush = new SolidBrush(Color.Black);
SolidBrush whiteBrush = new SolidBrush(Color.White);
graphics.FillRectangle(whiteBrush, 0, 0, bitMap.Width, bitMap.Height);
graphics.DrawString("*" + barCodeBlack + "*", oFont, blackBrush, point);
}
using (MemoryStream ms = new MemoryStream(100000))
{
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] byteImage = ms.ToArray();
Convert.ToBase64String(byteImage);
imgBarCodeBlack.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteImage);
}
PlaceHolder1.Controls.Add(imgBarCodeBlack);
}
}
<div class="col-xs-12 col-sm-12 col-lg-12" style="margin-bottom:20px;">
<h3>Digital Black</h3>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</div>
UPDATE
Okay I tried searching for other solution, and I found the answer.
I changed this line:
using (Bitmap bitMap = new Bitmap(barCodeBlack.Length * 40, 80))
to this line:
using (Bitmap bitMap = new Bitmap(800, 80))
for some reason the new Bitmap does not accept variable inside the parameter, so I guess I need to hard code my measurement of the barcode.
I have a function in my code behind that does what I want. What I like about this is no matter how the user expand his drawing out of the InkCanvas boundries, the image will be resized when saved.
private void exportCanvasToBitmap(object sender, EventArgs e) {
RenderTargetBitmap rtb = new
RenderTargetBitmap((int)signatureCanvas.ActualWidth,
(int)signatureCanvas.ActualHeight, 96, 96, PixelFormats.Default);
rtb.Render(signatureCanvas);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
FileStream fs = File.Open(#".\images\"+ signatureFileName + ".jpg", FileMode.Create);
encoder.Save(fs);
fs.Close();
(sourceWindow as MainWindow).updateSignatureImage(signatureType, signatureFileName);
}
I wanted to move this to the ViewModel and I didn't know how to make it does the same as the one I have before. I don't want to usertb.Render(inkCanvas) in the ViewModel. After some search I binded a StrokeCollection to my view and used this function.
public void convertStrokestoImage() {
StrokeCollection sc = strokes;
byte[] inkData = null;
using (MemoryStream inkMemStream = new MemoryStream())
{
sc.Save(inkMemStream);
inkData = inkMemStream.ToArray();
}
byte[] gifData = null;
using (Microsoft.Ink.Ink ink2 = new Microsoft.Ink.Ink())
{
ink2.Load(inkData);
gifData = ink2.Save(Microsoft.Ink.PersistenceFormat.Gif);
}
File.WriteAllBytes("./Src/strokes.png", gifData);
}
The problem with this is that if the user draws out of the InkCanvas' boundaries, the image scales " which I don't want". I am not really sure how to do that since both of the function I found online as solutions in other questions.
My initial thought is that I have to do something similar for what I had before where I had a RenderTargetBitmap that has the actual width and height of my InkCanvas. The issue is I don't know how to obtain this without using InkCanvas object itself.
any tips?
I solved the issue like this.
First I converted the byte[] to an Image and then I used a helper function to resize the image.
public void convertStrokestoImage()
{
StrokeCollection sc = strokes;
byte[] inkData = null;
using (MemoryStream inkMemStream = new MemoryStream())
{
sc.Save(inkMemStream);
inkData = inkMemStream.ToArray();
}
byte[] gifData = null;
using (Microsoft.Ink.Ink ink2 = new Microsoft.Ink.Ink())
{
ink2.Load(inkData);
gifData = ink2.Save(Microsoft.Ink.PersistenceFormat.Gif);
}
MemoryStream ms = new MemoryStream(gifData);
Image image = Image.FromStream(ms);
image = resizeImage(image, 100, 150);
image.Save("./Src/strokes.png");
}
You can find alot of functions to resize images in the following question.
Resize an Image C#
What I don't like about this is the image file size become bigger!
For example what was 5kb became 30kb.
i have two images the first one for product , and the second one for Barcode of product .
i use to create product this code
private void button1_Click(object sender, EventArgs e)
{
string barcode = CMBIDCAT.Text+"345" + TXTIDP.Text +"012" ;
Bitmap bitmap = new Bitmap(barcode.Length * 20, 50);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
Font ofont = new Font("code 128", 30);
PointF point = new PointF(2f, 2f);
SolidBrush blackbursh = new SolidBrush(Color.Black);
SolidBrush whitebursh = new SolidBrush(Color.White);
graphics.FillRectangle(whitebursh, 0, 0, bitmap.Width, bitmap.Height);
graphics.DrawString("*" + barcode + "*",ofont, blackbursh, point);
}
using (DataTable dt = new DataTable())
{
PIC2.Image = bitmap;
PIC2.Height = bitmap.Height;
PIC2.Width = bitmap.Width;
}
private void button3_Click(object sender, EventArgs e)
{
MemoryStream ms = new MemoryStream();
PIC1.Image.Save(ms, PIC1.Image.RawFormat);
byte[] byteImage = ms.ToArray();
MemoryStream st = new MemoryStream();
PIC2.Image.Save(st, PIC2.Image.RawFormat);
byte[] byteImage1 = st.ToArray();
prd.ADD_PRODUCT(Convert.ToInt32(CMBIDCAT.SelectedValue), TXTIDP.Text, TXTNMP.Text, Convert.ToInt32(TXTFP.Text), Convert.ToInt32(TXTSP.Text), Convert.ToInt32(TXTTP.Text), TXTDES.Text, Convert.ToInt32(TXTQTE.Text), byteImage, byteImage1);
MessageBox.Show("تمت الاضافة بنجاح ", "عملية الاضافة",MessageBoxButtons.OK , MessageBoxIcon.Information);
}
i don't know the reason for this issue please any one help me
how can i solve this please .
I don't have the rep to just comment. But, should you be using a new MemoryStream for your second image?
According to the MSDN you should not write to a stream that has been written to.
MSDN "Image.Save Method (Stream, ImageFormat)"
Change your code to:
MemoryStream ms = new MemoryStream();
PIC1.Image.Save(ms, PIC1.Image.RawFormat);
byte[] byteImage = ms.ToArray();
MemoryStream ms1 = new MemoryStream();
PIC2.Image.Save(ms1, PIC2.Image.RawFormat);
byte[] byteImage1 = ms1.ToArray();
Hopefully that works. :)
Make sure which value is null while debugging whether the Format or the stream, and consider using the "using" statement with memory stream in order for the resources to be freed like the following :
byte[] byteImage1;
using(MemoryStream ms = new MemoryStream())
{
PIC1.Image.Save(ms, PIC1.Image.RawFormat);
byteImage1 = ms.ToArray();
}
And consider using two memory streams for each image as #Tim.E suggested.
I can dynamically create a barcode using sample tutorials.
This block of code is in a loop and generates a number of images determined by user input. The image is in a place holder and is displayed on the same webpage.
I want the user to be able to have all the images on a separate page or file for them to print, but I'm not quite sure the best approach to do that. I tried placing it in a session, but I only get 1 image as opposed to the amount the user entered.
System.Web.UI.WebControls.Image imgBarCode = new System.Web.UI.WebControls.Image();
using (Bitmap bitMap = new Bitmap(barCode.Length * 27, 100))
{
using (Graphics graphics = Graphics.FromImage(bitMap))
{
Font oFont = new Font("IDAutomationHC39M", 16);
PointF point = new PointF(2f, .2f);
SolidBrush blackBrush = new SolidBrush(Color.Black);
SolidBrush whiteBrush = new SolidBrush(Color.White);
graphics.FillRectangle(whiteBrush, 0, 0, bitMap.Width, bitMap.Height);
graphics.DrawString("*" + barCode + "*", oFont, blackBrush, point);
}
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
bitMap.Save(ms, ImageFormat.Png);
byte[] byteImage = ms.ToArray();
Convert.ToBase64String(byteImage);
imgBarCode.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteImage);
}
plBarCode.Controls.Add(imgBarCode);
}
i have an asp.net website, and i want to print some barcodes in c#. i use "IDAutomationHC39M" font as bellow:
public static void PrintSmallBarcode(HtmlGenericControl divBarCode, string barCode)
{
System.Web.UI.WebControls.Image imgBarCode = new System.Web.UI.WebControls.Image();
using (Bitmap bitMap = new Bitmap(75, 18))
{
using (Graphics graphics = Graphics.FromImage(bitMap))
{
Font oFont = new Font("IDAutomationHC39M", 7);
PointF point = new PointF(0, 0);
SolidBrush blackBrush = new SolidBrush(Color.Black);
SolidBrush whiteBrush = new SolidBrush(Color.White);
graphics.FillRectangle(whiteBrush, 0, 0, bitMap.Width, bitMap.Height);
graphics.DrawString(barCode, oFont, blackBrush, point);
}
using (MemoryStream ms = new MemoryStream())
{
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] byteImage = ms.ToArray();
Convert.ToBase64String(byteImage);
imgBarCode.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteImage);
imgBarCode.CssClass = "cssbarcode";
}
}
div.Controls.Add(imgBarCode);
}
it works, but the quality of barcode is sow low, and my barcode reader device failed to read it. i can not increase the size of image, and of course i see a lot of good barcodes smaller than my size. i replace "IDAutomationHC39M" font with "free3of9.ttf", but this font just draw the number and no barcode line!.
how can i get a better barcode?
This is a long-standing problem with barcode fonts; they are enormous and scan horribly because printers try to anti-alias the bars.
Use images, not fonts, to draw barcodes. There are many packages available, for example Barcode Rendering Framework.
You can use other datas to change the size of the barcode.I used keepautomation barcode generator for asp.net to create barcode images in Visual C# ASP.NET project.After my settings,i can preview the size of the barcode.