Comments (6)
There is no trick and there is no implementation.
And, as far as I know, it isn't that easy. You do not only have to replace the FNC1 character, you also need to know the structure of the code. There are fixed length and variable length elements which depend on the used identifiers.
You can write a wrapper around the Renderer class which replaces the FNC1 elements and adds the brackets before generating the image.
private class GS1Renderer : BitmapRenderer
{
public override Bitmap Render(BitMatrix matrix, BarcodeFormat format, string content, EncodingOptions options)
{
// modify the content before rendering the image
// it doesn't change the bitmatrix, it's only for the text beneath the code
// following replace is only a sample
// add a more complex algorithm here
content = content.Replace($"{(char)0x00F1}", "(");
// call the base class to render the barcode image
return base.Render(matrix, format, content, options);
}
}
and use it with the BarcodeWriter
var writer = new BarcodeWriter
{
Format = BarcodeFormat.CODE_128,
Renderer = new GS1Renderer()
};
var barcodeImage = writer.Write($"{(char)0x00F1}0123454689");
from zxing.net.
okay, I try it later.
Is it right, that the content is Change before the Barcode is rendered?
The Barcode must have the FNC1-char, but the text under the Barcode must human-readable.
So when I change it before rendering, than I change the Barcode too.
from zxing.net.
What do you mean with "Didn't work for me."?
As I said before if you modify the content parameter in the method "Render" than only the readable text will be modified. The barcode contains the original, unmodified content.
from zxing.net.
Does it work now?
from zxing.net.
I too have just encountered this issue and the suggestion made by @micjahn to write a wrapper around the Render
method of the BitmapRenderer
class put me on the right track to come up with a solution for what I was wanting to achieve.
I thought I would document this here, in the hope that this will also help others that find themselves facing this issue or similar.
This basically expands on the content.Replace($"{(char)0x00F1}", "(");
code that @micjahn used in his example. It seems it's easy enough to get the first (
in place, but trying to figure out where to put the closing )
seemed to be a bit more complicated.
In my case, I was trying to create Barcode images (on the fly) and serve them up via HTTP. The data for the barcode is supplied through a querystring parameter named data
along with other parameters, which is used to generate the relevant barcode image.
The problem I faced here was trying to identify where the separation of items should occur within the value supplied through data
.
So, within the data
string value, I am separating each item with a hyphen -
or dot/period .
.
- Occurrences of the
-
character indicate where a field separator should be inserted - Occurrences of the
.
character indicate a separation of fields but does NOT require a field separator to be inserted.
An example of the URL I would call to generate a barcode image and serve back to the browser:
http://mysite.com/Barcode/?data=0200000000000023.11171115.3700456000-10664202&type=code128&margin=70
This results in the following barcode:
(02)00000000000023 (11)171115 (37)00456000 (10)664202
I created an MVC application and created a controller and action to handle this as well as a custom renderer class GS1Renderer
to handle the generation of the barcode number that is placed at the bottom of the image.
The code for this is provided below:
public class BarcodeController : Controller
{
/// <summary>
/// Generates a barcode and returns it to the browser as a PNG image
/// </summary>
/// <param name="data">The data that is to be used on the barcode</param>
/// <param name="width">The width that is to be used when generating the barcode</param>
/// <param name="height">The height that is to be used when generating the barcode</param>
/// <param name="margin">The size that is to be set around the barcode</param>
/// <param name="type">Specifies the type of barcode that is to be generated</param>
/// <returns>A byte array that will be streamed to the browser</returns>
[HttpGet]
public ActionResult Index(string data, int width = 200, int height = 200, int margin = 0, string type = "qr")
{
// Defne a byte array.
// This is the varaible that we will use to return the data back to the browser.
byte[] fileContent;
// Set the options that we will use for creatung the barcode
var options = new QrCodeEncodingOptions
{
Width = width,
Height = height,
Margin = margin
};
// We need to to determine what format the barcode is to be.
// This will default to the QR Code format
var format = BarcodeFormat.QR_CODE;
switch (type.ToLower())
{
case "qr":
format = BarcodeFormat.QR_CODE;
break;
case "code128":
format = BarcodeFormat.CODE_128;
break;
default:
format = BarcodeFormat.QR_CODE;
break;
}
// Create an istance of the BarcodeWriter, setting the relevant Options and Format
var bw = new BarcodeWriter { Format = format, Options = options };
// If the type of barcode being rendered is GS1-128,
// Then assign an instance of GS1Renderer to the Renderer property.
// This will allow us to perform custom logic just before the barcode image is generated.
if (type.ToLower() == "code128")
{
bw.Renderer = new GS1Renderer();
((GS1Renderer)bw.Renderer).SetFriendlyContent(data);
char fnc1 = (char)0x00F1;
data = $"{fnc1}{data}";
// NOTE:
// - Occurrences of the '-' character indicate where a field separtor should be inserted
// - Occurrences of the '.' character indicate a separation of fields but does NOT require a field separator to be inserted
data = data.Replace("-", $"{fnc1}");
data = data.Replace(".", "");
}
// Create the relevant Barcode as a Bitmap
// We will use this later to convert it to a PNG file.
var bitmapBarcode = bw.Write(data);
// Create a MemoryStream and save the bitmap to it using the PNG format.
// then get the Byte array from the stream, as this is the data we want to send back to the browser.
using (var ms = new MemoryStream())
{
bitmapBarcode.Save(ms, ImageFormat.Png);
fileContent = ms.ToArray();
}
// Send the Byte array back to the browser.
// This will serve the barcode up as a PNG image.
return File(fileContent, "image/png");
}
}
The code for the Custom Renderer class is provided below:
public class GS1Renderer : BitmapRenderer
{
/// <summary>
/// Will contain a value used for number at the bottom of the barcode image
/// </summary>
private string _friendlyContent;
public override Bitmap Render(BitMatrix matrix, BarcodeFormat format, string content, EncodingOptions options)
{
// If the _friendlyContent has been set, then we will use this value for the content.
// Otherwise, we will just use the original content.
content = (!string.IsNullOrWhiteSpace(_friendlyContent)) ? _friendlyContent : content;
// Call the base class to render the barcode image
return base.Render(matrix, format, content, options);
}
/// <summary>
///
/// </summary>
/// <param name="data">The data content that is to be modified to be in a more user friendly and readable format</param>
public void SetFriendlyContent(string data)
{
string newContent = string.Empty;
// Define a list of Application Identifier Values.
// We will use this list to identify strings that contain data for the relevant Application Identifiers.
List<string> appIds = new List<string> { "00", "02", "11", "10", "37" };
// TODO:
// Add the relevant Application Identifier Values to the appIds list as required
// Split the data string at each occurrence of the '-' and '.' characters.
// This should give us a list of strings, each one representing data relating to a specific Application Identifier.
var barcodeItems = data.Split(new char[] { '-' , '.' }, StringSplitOptions.RemoveEmptyEntries).ToList();
if(barcodeItems != null & barcodeItems.Any())
{
// Loop through each of the items and check if it starts with one of the Application Identifiers in out list.
// If it does, then we will extract the relevant data value from the item.
// We will use the extracted data to bulid a string for the current item to be in a more readable format that clearly separates Application Identifier and it's assiciated data.
// e.g. (11)171115
foreach (var item in barcodeItems)
{
appIds.ForEach(id =>
{
if (item.StartsWith(id))
{
string itemValue = item.Substring(id.Length);
newContent += $"({id}){itemValue}";
}
});
}
}
// Only assign a value to _friendlyContent if the newContent has been set.
if (!string.IsNullOrWhiteSpace(newContent))
{
_friendlyContent = newContent;
}
}
}
from zxing.net.
Thanks for sharing your solution.
from zxing.net.
Related Issues (20)
- Unable to parse this QR code, I don't know why HOT 1
- QRCODE type error parsing to UPC-E type HOT 1
- UPC/EAN Extension 2/5 does not read the 2/5 digit extension
- Can someone finally fix the example usage in README?
- Don't decode QR_CODE HOT 3
- ZXing.Net doesn't seem to be able scan more complicated PDF417 barcodes HOT 12
- EPC QR Code (European Payments Council) Not Decoded HOT 3
- Support for Latin-1 in BARCODE-128 HOT 4
- Upgrade SixLabors.ImageSharp - current version has vulnerabilities HOT 1
- UPC_A's error message is wrong.
- The image for PLESSEY is vertically tiny. HOT 6
- The sides of UPC_A's image could be slightly cut out. HOT 1
- Centering PDF_417 Barcodes and Unstable Width/Height HOT 1
- Barcode as small part of image HOT 1
- Barcode generator: unpredictable whitespace padding around it depending on requested Width
- Upgrading to Magick.Net 13.7.0 breaks ZXing.Magick HOT 1
- ZXing for WinUI-3 HOT 1
- Barcode DATA_MATRIX code = BCD88888888-1 to BCD88888888-99 Don't look right they are not a sqaure
- Undecodable QR code generated
- Recognizes the UPC_E format on the Qr_CODE HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from zxing.net.