barcodelib
barcodelib copied to clipboard
Barcodelib 2.4.0 compatibility with 3.0.0
It seems the new version is not compatible with the previous one 2.4.0.
E.g. the code var barcode = new BarcodeLib.Barcode()
causes compilation errors.
When I tried to change the namespace from BarcodeLib
to BarcodeStandard
then parameters like HoritontalResolution
were not supported.
Please, could you provide updated examples to understand how to use the new version of the library?
I found this example. If you are working on windows you can export the barcode as System.Drawing.Image. On other platforms use SKImage.
using BarcodeStandard;
using SkiaSharp;
using System.Text.RegularExpressions;
using System.Drawing;
namespace Common.Services.Helpers
{
public class BarcodeGenerator
{
private static SKImage GetImage(string text, Type type)
{
var barcode = new Barcode();
var regex = new Regex(@"^[0-9]+$");
bool bcType = regex.IsMatch(text);
barcode.IncludeLabel = false;
barcode.Height = 76;
barcode.BarWidth = bcType ? 3 : 2; // 3 for numeric value, 2 for string
return barcode.Encode(type, text, SKColors.Black, SKColors.White);
}
public static Image Code128(string text)
{
var img = GetImage(text, Type.Code128);
return Image.FromStream(img.Encode().AsStream());
}
}
}
This was done to support more platforms besides windows. SkiaSharp is the path to multi-platform support. :)
You did point out that the symbology namespace was never converted to BarcodeStandard but still resides in BarcodeLib. I will fix that.
Yeah I have the same issue after upgrading from 2.4.0 to 3.0.0. I have reverted back to 2.4.0. I'll wait for your next release after you fix it. Thanks.
It follows that the examples at https://github.com/barnhill/barcodelib/blob/master/README.md should be updated.
I upgraded to 3.0 and it busted my app but I have it working now. Here is another example. I hope it helps someone out. Even though this is for a WPF app and it returns a BitmapFrame, it is well commented, and you can see it's easy to do what you want with the barcode image.
First add your usings:
using BarcodeStandard;
using SkiaSharp;
Then your method:
`public static BitmapFrame Create(int barcodeNum) { // I'm writing the barcode onto a client card, you can ignore this if you don't need it. string path = Path.Combine(MyApplication.PathToExecutable!, "resources\panb-client-card.bmp"); using Bitmap bm = new(path);
// 👉 Create the barcode using the library.
BarcodeStandard.Barcode barcode = new()
{
IncludeLabel = true,
Alignment = AlignmentPositions.Center,
ImageFormat = SkiaSharp.SKEncodedImageFormat.Png,
LabelFont = new SKFont(SKTypeface.Default, 18),
};
// Create an SkImage from the barcode of Code39 of 200x65 and then from that, create a System.Drawing image.
var skImage = barcode.Encode(Type.Code39, barcodeNum.ToString(), 200, 65);
var drawingImage = Image.FromStream(skImage.Encode().AsStream(), true);
// You can do what you want with the drawingImage but in this case I'm going to draw the barcode (drawingImage)
// on a bitmap of a client card.
using (System.Drawing.Bitmap bitmapBarcode = new(drawingImage))
{
using Graphics g = Graphics.FromImage(bm);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(bitmapBarcode, 50, 130);
}
// Here is where you can save the image. You could save to disk but in this case, I'm going to return a BitmapFrame.
// bm.Save("C:\\Users\\xxxx\\Downloads\\test\\test3.png", ImageFormat.Png);
using MemoryStream memoryStream = new();
bm.Save(memoryStream, ImageFormat.Png);
return BitmapFrame.Create(memoryStream, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnLoad);
}`
Yes I had to get away from using System.Drawing.Bitmap
in the library to support cross platform generation of barcodes.
@barnhill have you got an example of how to output this to a FileContentResult without the reliance on System.Drawing?
@nfplee : look at this example and linkt to documentation https://github.com/barnhill/barcodelib/issues/156#issuecomment-1568355374. You can delete the reference to System.Drawing and use only SKImage:
using BarcodeStandard;
using SkiaSharp;
using System.Text.RegularExpressions;
namespace Common.Services.Helpers
{
public class BarcodeGenerator
{
private static SKImage GetImage(string text, Type type)
{
var barcode = new Barcode();
var regex = new Regex(@"^[0-9]+$");
bool bcType = regex.IsMatch(text);
barcode.IncludeLabel = false;
barcode.Height = 76;
barcode.BarWidth = bcType ? 3 : 2; // 3 for numeric value, 2 for string
return barcode.Encode(type, text, SKColors.Black, SKColors.White);
}
}
}
@kzimny thanks. I ended up with:
public IActionResult Barcode(string text)
{
using var ms = new MemoryStream();
using var barcode = new Barcode()
{
Alignment = AlignmentPositions.Left,
IncludeLabel = false
};
barcode.Encode(Type.Code39, text, 300, 80);
barcode.SaveImage(ms, SaveTypes.Png);
return File(ms.ToArray(), "image/png");
}
Having looked at the source code, it looks like adding a using statement when initiating the barcode should dispose of the SKImage
returned from the Encode
method. This works because the Encode
method sets the EncodedImage
property of the Barcode
type to the image returned and calls it's Dispose
method when the Barcode
itself is disposed.
This was done to preserve memory space when done with the barcode object. I think this would be expected behavior?