barnhill / barcodelib

C# Barcode Image Generation Library
Apache License 2.0
733 stars 238 forks source link

Barcodelib 2.4.0 compatibility with 3.0.0 #156

Open OndrejUzovic opened 1 year ago

OndrejUzovic commented 1 year ago

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?

kzimny commented 1 year ago

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());
        }
    }
}
barnhill commented 1 year ago

This was done to support more platforms besides windows. SkiaSharp is the path to multi-platform support. :)

barnhill commented 1 year ago

You did point out that the symbology namespace was never converted to BarcodeStandard but still resides in BarcodeLib. I will fix that.

KC7465128305 commented 1 year ago

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.

MikeRosoft commented 1 year ago

It follows that the examples at https://github.com/barnhill/barcodelib/blob/master/README.md should be updated.

meineGlock20 commented 1 year ago

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);

}`

barnhill commented 11 months ago

Yes I had to get away from using System.Drawing.Bitmap in the library to support cross platform generation of barcodes.

nfplee commented 10 months ago

@barnhill have you got an example of how to output this to a FileContentResult without the reliance on System.Drawing?

kzimny commented 10 months ago

@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);
        }
    }
}
nfplee commented 10 months ago

@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.

barnhill commented 4 months ago

This was done to preserve memory space when done with the barcode object. I think this would be expected behavior?