Support for Latin-1 in BARCODE-128
Hello,
we've been using this library to create barcodes in our project. It works well, but we've stumbled upon one limitation - the library explicitly does not support full Latin-1 charset. Some of our clients in scnadinavia use the special characters, and our app can't give them a nice PDF with a readable barcode.
Are there plans to add support for full Latin-1 charset? Maybe there is a workaround we can use?
Appreciate your answer and your work on the library!
Can you please post a code snippet which shows how you generate the code?
Sure thing. This is the whole method that receives user input and returns a byte array with the barcode:
private static byte[] GetBarCode(string contents)
{
byte[] byteArray;
var codeWriter = new ZXing.BarcodeWriterPixelData
{
Format = ZXing.BarcodeFormat.CODE_128,
Options = new QrCodeEncodingOptions
{
Width = 140,
Height = 40,
Margin = 0,
NoPadding = true
}
};
var pixelData = codeWriter.Write(contents);
var bitmap = new SKBitmap();
var gcHandle = GCHandle.Alloc(pixelData.Pixels, GCHandleType.Pinned);
var info = new SKImageInfo(pixelData.Width, pixelData.Height, SKImageInfo.PlatformColorType, SKAlphaType.Unpremul);
bitmap.InstallPixels(info, gcHandle.AddrOfPinnedObject(), info.RowBytes, delegate { gcHandle.Free(); }, null);
using var image = SKImage.FromBitmap(bitmap);
using var data = image.Encode(SKEncodedImageFormat.Png, 100);
using var writeStream = new MemoryStream();
data.SaveTo(writeStream);
byteArray = writeStream.ToArray();
return byteArray;
}
At the moment ZXing.Net doesn't support Latin-1 without manually switching to the FNC4 mode. I fear I will not find enough free time to add that function. That means you can only use the following "hack". I tested the code only with the german characters 'ä' and 'Ä'. Perhaps it doesn't work for all Latin-1 characters. ZXing.Net decodes it successfully. But be aware of the perhaps not all readers support FNC4.
private static byte[] GetBarCode(string contents)
{
byte[] byteArray;
var codeWriter = new ZXing.BarcodeWriterPixelData
{
Format = ZXing.BarcodeFormat.CODE_128,
Options = new ZXing.OneD.Code128EncodingOptions
{
Width = 140,
Height = 40,
Margin = 0,
NoPadding = true
},
Renderer = new PixelDataRendererWrapper()
};
var pixelData = codeWriter.Write(AddFNC4(contents));
var bitmap = new SKBitmap();
var gcHandle = GCHandle.Alloc(pixelData.Pixels, GCHandleType.Pinned);
var info = new SKImageInfo(pixelData.Width, pixelData.Height, SKImageInfo.PlatformColorType, SKAlphaType.Unpremul);
bitmap.InstallPixels(info, gcHandle.AddrOfPinnedObject(), info.RowBytes, delegate { gcHandle.Free(); }, null);
using var image = SKImage.FromBitmap(bitmap);
using var data = image.Encode(SKEncodedImageFormat.Png, 100);
using var writeStream = new MemoryStream();
data.SaveTo(writeStream);
byteArray = writeStream.ToArray();
return byteArray;
}
private string AddFNC4(string content)
{
// zxing doesn't add the FNC4 automatically at the moment
// it has to be added manually
var builder = new System.Text.StringBuilder(content.Length);
foreach (var ch in content)
{
if (ch > 128)
{
builder.Append('\u00f4');
builder.Append((char)(ch - 128));
}
else
{
builder.Append(ch);
}
}
return builder.ToString();
}
public class PixelDataRendererWrapper : ZXing.Rendering.IBarcodeRenderer<ZXing.Rendering.PixelData>
{
private ZXing.Rendering.PixelDataRenderer renderer = new ZXing.Rendering.PixelDataRenderer();
public PixelData Render(BitMatrix matrix, BarcodeFormat format, string content)
{
return renderer.Render(matrix, format, ReplaceFNC4(content));
}
public PixelData Render(BitMatrix matrix, BarcodeFormat format, string content, EncodingOptions options)
{
return renderer.Render(matrix, format, ReplaceFNC4(content), options);
}
private string ReplaceFNC4(string content)
{
var builder = new System.Text.StringBuilder(content.Length);
var fnc4Found = false;
foreach (var ch in content)
{
if (ch == '\u00f4')
fnc4Found = true;
else
{
if (fnc4Found)
{
builder.Append((char)(ch + 128));
fnc4Found = false;
}
else
{
builder.Append(ch);
}
}
}
return builder.ToString();
}
}
Thanks a lot @micjahn, appreciate your workaround! It'll help us a lot. I suppose you can close this issue if you think it's appropriate.