I want to generate a 1D EAN8 barcode using c# Zxing. I have only been able to find code examples and documentation for generating 2D QR-code
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions
{
Height = height,
Width = width
}
};
return writer.Write(textForEncoding);
which I can run and works fine, but there is no "1DCodeEncodingOptions" or similarly named function. I tried
var writer = new BarcodeWriter
{
Format = BarcodeFormat.EAN_8
};
return writer.Write("1234567");
but it throughs an index error.
edit: I have the syntax correct now but it is not producing a proper barcode because I do not know the size it expects, and there seems to be no default.
using ZXing;
Using ZXing.OneD
var writer = new BarcodeWriter
{
Format = BarcodeFormat.EAN_8,
Options = new ZXing.Common.EncodingOptions
{
Height = 100,
Width = 300
}
};
return writer.Write("12345678");
12345678 is not a valid EAN8 barcode. The check digit for 1234567 is 0. See EAN 8 : How to calculate checksum digit? for how to calculate checksums.
ZXing won't stop you creating invalid barcodes (at least in the version 0.11 I'm using, although the current source on Codeplex looks like it does), but they won't scan. The scanner uses the checksum to ensure that it has read the data correctly.
If you intend to use an EAN8 in commerce, you will need to get a GTIN-8 from your national GS1 Member Organization. If you only intend to sell them in your store, you should use one of the restricted distribution prefixes.
If you don't need to put your products in the retail supply chain, I'd recommend a different barcode format.
Interleaved 2 of 5 (BarcodeFormat.ITF) is very compact but can only contain digits; it doesn't have any self-checking and there's a design flaw that allows the barcode to be misread from some angles. It's recommended that you put black bars (called Bearer Bars) across the top and bottom of the barcode. I can't see an option for this in ZXing.
The next most compact format is Code 128 (BarcodeFormat.CODE_128), using Code Set C. This encodes two digits in one module (one block of six bars and spaces). The format is self-checking (there is always a check character, which is stripped off by the scanner). Some scanners don't handle Code Set C properly. To force Code Set B, use Code128EncodingOptions in place of Common.EncodingOptions and set ForceCodesetB to true.
Related
how can I convert an EAN-13 or Code-128 barcode generated from a weighing scale machine back to a user-defined object?
Class Product
{
string name = "Apples";
deciaml qty = "0.5";
double value = "5";
}
I already found libraries but all decodes barcode provided as an image. in my case, I have a barcode reader which will be reading the barcode label and input it as numbers something like (2032156478954).
what library or how can I decode those barcode numbers back to my object?
assume that I know from the user manual of the weighing scale which part is the product name, qty, and value
just like those label barcode we see in hypermarkets where you buy fruits and veggies in KG or Gram, it prints a barcode label, then the barcode label on POS is converted back to product object.
I am totally new when it comes to handling barcodes in .NET, any help, suggestion, or advice will be appreciated.
Example of Weighing Scale Barcode
Currently, I have solved it by implementing my own solution.
assume the barcode is 2 53647 2 5262 9 (EAN-13)
from the left-hand side, 2 tells the POS this is a barcode from the weighing scale machine, 53647 will be the ID of the item in the database.
2 tells the POS next 5 digits are the price of the item (52.62)
the last digit always discarded
the downside of this method is you will have to change either the settings of your weighing machine for every new setup you make to match your function. or you will change your code to match how the machine is printing barcodes since there is no one international standard.
I was hoping for a library that would have built-in functionality to recognize and decode those barcodes based on leading numbers and other check numbers. I might start building my own after looking at the most used formats.
If you already have a the string, as others pointed out you theoretically just nid to split the barcode and fill you class.
If you have a look here:
https://www.codeproject.com/Articles/10162/Creating-EAN-13-Barcodes-with-C
It shows you what the single numbers mean.
However:
If you want to figure out the values behind the numbers, then thats a little bit tricky. I expect the manufacturer code, if internationally standardized is something that will change over time. Because someone registers a new manufacturer and therefore gets a new code.
This would imply your programm needs access to the internet resp. to this database where they are registered.
Before putting to much effort in it, ask you self:
Do I really need to have this informations that well prepared, for the project am I'm doing or would it be completely fine if you just split the strings and have as manufacturer for example "50603" without knowing whats behind.
I just give you this sample for the EAN code, but I would say you can apply this to other codes as well.
The task that i have is to create a replica of a search engine that converts measurements. The user enters "4cm to inches" and the program makes the appropriate calculations to give the answer in inches. Now this program must be able to convert through a range of different measurements and dimensions eg Volume and area also. So far i have been able to make it convert strictly from cm to inches using properties of strings ie Substring, IndexOf, Convert.Toint16 and i want it to continue doing so but i'm struggling modularising it so that it can do a range of different calculations efficiently. This is what i have so far...
Toconvert = Console.ReadLine();
Cmpos = Toconvert.IndexOf("cm");
Inchespos = Toconvert.IndexOf("inches");
CmUnits = Toconvert.Substring(Cmpos, 2);
InchesUnits = Toconvert.Substring(Inchespos, 6);
number2convert = Convert.ToInt16(Toconvert.Substring(0, Cmpos));
Inches = number2convert / 2.54;
Console.WriteLine("{0}{1} is {2:F2} {3}", number2convert, CmUnits, Inches, InchesUnits);
Console.ReadLine();
This is very problematic/limiting and has me perplexed. Every route ive taken ive encountered an error of some sort.
All i want it to do is read whats been input by the user, and outputs the appropriate value from what the computer has.
Learn Regex, it will be your friend, especially for something like this.
Here's a query that will help for your particular case:
([0-9]+[.]?[0-9]*)[\s]*([\w]+)[\s]+[\w]+[\s]+([\w]+)
Loosely translated: Look for numbers (4), then a space or not, then a word (cm), then space, then a word (to), then space, then a word (inches).
Regex offers "groups" (the items in parentheses). for 4cm to inches in the above Regex, the groups are 4, cm and inches...all the useful bits.
This is an example of it in use. There's also very good explanations for each step of the Regex (Click on the "Explain" tab).
Here's a C# example:
var reg = new System.Text.RegularExpressions.Regex(#"([0-9]+[.]?[0-9]*)[\s]*([\w]+)[\s]+[\w]+[\s]+([\w]+)");
var match = reg.Match("4cm to inches");
double numberToConvert = double.Parse(match.Groups[1].Value);
string fromUnits = match.Groups[2].Value;
string toUnits = match.Groups[3].Value;
I've been trying to read some values out of the metadata of a .mov file (QuickTime File Format) with limited success. I've been using the following link as a reference:
Introduction to QuickTime File Format Specification
I've managed to correctly locate and read out/calculate the media duration, but I can't seem to find which Atom the Bit Rate information is stored in. (Atoms are the internal blocks of metadata inside the file).
If anyone can point me to the correct Atom to read, I'll be alright reading it... I just can't seem to find it in the documentation even. "Bit Rate" is only mentioned a couple of times in the whole document.
UPDATE >>>
Going by the very limited information provided below by #szatmary, I have parsed the Sample Size Atom and the Time to Sample Atom from the relevant Track Atom, but am getting some bizarre values. For example, I keep getting a Sample Size value of 1 (when reading from multiple different single video .mov files with constant Bit Rates). The related documentation (from the above link) says:
Sample size
A 32-bit integer specifying the sample size. If all the samples are the same size, this field contains that size value. If this field is set to 0, then the samples have different sizes, and those sizes are stored in the sample size table.
So the field has the value of 1, which means that all samples have the same size, and the Number of entries [in the Sample Size Table] field matches that of the Sample Count field in the single entry of the Time to Sample Table (some very large number). The documentation states this:
... if a video media has a constant frame rate, this table would have one entry and the count would be equal to the number of samples.
So the video has a constant Bit Rate. However, when reading the size entries from the Sample Size Table, they are all different and non-sensical... some are 0, while others are very large numbers up to around 40000. Why are they different if the video has a constant Bit Rate, or should I not be reading them in this case?
Another issue that I have found is that the single entry in the Time to Sample Table of the Time to Sample Atom has the following values:
Sample Count: some very large number (expected)
Sample Duration: 1
Unfortunately the documentation (from the above link) is very light here:
Time-to-sample table
A table that defines the duration of each sample in the media. Each table entry contains a count field and a duration field.
So what units do these 1 values use (Sample Duration & Sample Size)?
Any further help with calculating the correct Bit Rate would be greatly appreciated. Please note that I have been taking the Big-Endian-ness of the file into consideration and reversing the bytes of each field value before reading them.
UPDATE 2 >>>
I have managed to work out that the Sampling Rate is calculated like this:
Media Duration = Duration / Timescale (from the Movie Header Atom or Track Header Atom)
Sampling Rate = Sample Count (from the Time-to-Sample Atom) / Media Duration
I just need to crack the Bit Rate now and further help is needed.
This will get you what you want, "The Bit Rate that is shown in Windows Explorer", but not from the QT metadata. If it is not appropriate for some reason, maybe it will work as a fallback solution until you can work out the Atom based answer or as something to compare the QT Atom results to.
In short, if you want what Explorer shows, get it from Explorer:
// add reference to Microsoft Shell controls and Automation
// from the COM tab
using Shell32;
class ShellInfo
{
// "columns" we want:
// FileName = 0;
const int PerceivedType = 9;
// FileKind = 11;
// MediaBitrate = 28;
// MediaLength = 27;
static int[] info = {0, 9, 11, 27, 28};
// note: author and title also available
public static Dictionary<string, string> GetMediaProperties(string file)
{
Dictionary<string, string> xtd = new Dictionary<string, string>();
Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder folder;
folder = shell.NameSpace(Path.GetDirectoryName(file));
foreach (var s in folder.Items())
{
if (folder.GetDetailsOf(s, 0).ToLowerInvariant() ==
Path.GetFileName(file).ToLowerInvariant())
{
// see if it is video
// possibly check FileKind ???
if (folder.GetDetailsOf(s, PerceivedType).ToLowerInvariant() ==
"video")
{
// add just the ones we want using the array of col indices
foreach (int n in info)
{
xtd.Add(folder.GetDetailsOf(folder.Items(), n),
folder.GetDetailsOf(s, n));
}
}
break;
}
// ToDo: freak out when it is not a video or audio type
// depending what you are trying to do
}
return xtd;
}
}
Usage:
Dictionary<string, string> myinfo;
myinfo = ShellInfo.GetMediaProperties(filepath);
The test file is a sample QT mov from Apple's site, so there is nothing special about it. The view in Explorer:
The results from GetMediaProperties:
The BitRate returned also matched the Audio BitRate returned by MediaProps and MediaTab (both use MediaInfo.DLL to gather all media property values).
The first 35 Shell extended properties are pretty well documented. I think as of Windows 7, this goes to 291(!). Many are file type specific for photos, emails etc. A few which may be of interest:
282: Data rate
283: Frame height
284: Frame rate
285: Frame width
286: Total bitrate
Data rate (282) is the Video BitRate (matches MediaInfo) ; Total Bitrate (286) is the combined a/v bitrate.
Windows 8 (UPDATE)
While the above code appears to run OK on Windows 7, for computers running Windows 8, to avoid a System.InvalidCastException on the following line...:
Shell shell = new Shell();
... the following code will need to be run to instantiate the Shell and Folder COM objects:
Type shellType = Type.GetTypeFromProgID("Shell.Application");
Object shell = Activator.CreateInstance(shellType);
Folder folder = (Folder)shellType.InvokeMember("NameSpace",
BindingFlags.InvokeMethod, null, shell,
new object[] { Path.GetDirectoryName(file) });
Solution found in the Instantiate Shell32.Shell object in Windows 8 question on the Visual Studio Forum.
Also, on Windows 8, it appears that more attributes have been added so that the maximum index is now 309 (with a few empty entries) and the above mentioned attributes have different indices:
298: Data rate
299: Frame height
300: Frame rate
301: Frame width
303: Total bitrate
It seems the returns from Shell32 has some characters in it which prevent a simple and direct conversion to an int value. For the Bit Rate:
string bRate = myinfo["Bit rate"]; // get return val
bRate = new string(bRate.Where(char.IsDigit).ToArray()); // tidy up
int bitRate = Convert.ToInt32(bRate);
Its not recorded anywhere. As a general rule, it is bad practice to store a value that can be calculated from other values. Plus bitrate can change over time with the same video. What you can do is add up the sizes of the frames you are interested in the stsz box (atoms are called boxes in the iso standard) and the sample durations from he stts box and to the math.
If you are OK to read informational value (you already have szatmary's answer for more accurate information), shell reports this by parsing the file and reading metadata through Media Foundation MPEG-4 Property Handler class.
Native API entry point for this is PSLookupPropertyHandlerCLSID and then regular COM instantiation for IPropertyStore interface and then reading the properties. Even if you don't have C# interface into this, you could easily get this through P/Invoke and interoperability layer.
The properties you can read this way are easily discovered by this helper app, wrapping the API: FilePropertyStore (Win32, x64). That is, what you see through the app is also available to you through the API mentioned.
Here is an excerpt from what it gets for a .MOV file (note PKEY_Audio_EncodingBitrate and PKEY_Video_EncodingBitrate):
## Property
* `PKEY_Media_Duration`, Length: `855000000` (`VT_UI8`) // `855,000,000`
* `PKEY_Audio_EncodingBitrate`, Bit rate: `43744` (`VT_UI4`) // `43,744`
* `PKEY_Audio_ChannelCount`, Channels: `1` (`VT_UI4`) // `1`
* `PKEY_Audio_Format`, Audio format: `{00001610-0000-0010-8000-00AA00389B71}` (`VT_LPWSTR`) // FourCC 0x00001610
* `PKEY_Audio_SampleRate`, Audio sample rate: `32000` (`VT_UI4`) // `32,000`
* `PKEY_Audio_SampleSize`, Audio sample size: `16` (`VT_UI4`) // `16`
* `PKEY_Audio_StreamNumber`: `1` (`VT_UI4`) // `1`
* `PKEY_Video_EncodingBitrate`, Data rate: `263352` (`VT_UI4`) // `263,352`
* `PKEY_Video_FrameWidth`, Frame width: `640` (`VT_UI4`) // `640`
* `PKEY_Video_FrameHeight`, Frame height: `480` (`VT_UI4`) // `480`
The method also works for other media file formats, getting data using the same keys through respective property handlers for other container formats.
How can I rewrite MATLAB pmtm function in Mathematica or C# (.NET 4.0)?
I am using pmtm in this way:
[p,f] = pmtm(data,tapers,n,fs);
Alternatively written without pmtm using spectrum.mtm and psd.
Hs = spectrum.mtm(tapers,'adapt');
powerspectrum = psd(Hs,data,'Fs',fs,'NFFT',n);
p = powerspectrum.data;
f = powerspectrum.Frequencies;
Where data is a column vector with 2048 elements, fs = 40, tapers = 8 and n = 2^nextpow2(size(data,1)) = 2048;
Thanks.
The pmtm (multitaper method) is a non-parametric method for computing a power spectrum similar to the periodogram approach.
In this method a power spectrum is computed by windowing the data and computing a Fourier transform, taking the magnitude of the result and squaring it. The multitaper method averages a pre-determined number of periodograms each computed with a different window. This method works because the selected windows have two mathematical properties. First, the windows are orthogonal. This means that each one of the periodograms is uncorrelated so averaging multiple periodograms gives an estimate with a lower variance than using just one taper. Second, the windows have the best possible concentration in the frequency domain for a fixed signal length. This means that these windows perform the best possible with respect to leakage.
Mathematica has package for time series that contains funtions like PowerSpectralDensity.
If you have further problems ask your question in https://mathematica.stackexchange.com/
I have a bunch of PDF files- I read these as requested into a byte array and then also pass it to a iTextSharp PdfReader instance. I want to then grab the dimensions of each page- in pixels. From what I've read so far it seems by PDF files work in points- a point being a configurable unit stored in some kind of dictionary in an element called UserUnit.
Loading my PDF File into a PdfReader, what do I need to do to get the UserUnit for each page (apparently it can vary from page to page) so I can then get the page dimensions in pixels.
At present I have this code, which grabs the dimensions for each page in "points" - guess I just need the UerUnit, and can then multiply these dimensions by that to get pixels or something similar.
//Create an object to read the PDF
PdfReader reader = new iTextSharp.text.pdf.PdfReader(file_content);
for (int i = 1; i <= reader.NumberOfPages; i++)
{
Rectangle dim = reader.GetPageSize(i);
int[] xy = new int[] { (int)dim.Width, (int)dim.Height }; // returns page size in "points"
page_data[objectid + '-' + i] = xy;
}
Cheers!
Allow me to quote from my book:
iText in Action - Second Edition, page 9:
FAQ What is the measurement unit in PDF documents? Most of the measurements
in PDFs are expressed in user space units. ISO-32000-1 (section 8.3.2.3) tells us
“the default for the size of the unit in default user space (1/72 inch) is
approximately the same as a point (pt), a unit widely used in the printing
industry. It is not exactly the same; there is no universal definition of a point.”
In short, 1 in. = 25.4 mm = 72 user units (which roughly corresponds to 72 pt).
On the next page, I explain that it’s possible to change the default value of the user unit, and I add an example on how to create a document with pages that have a different user unit.
Now for your question: suppose you have an existing PDF, how do you find which user unit was used? Before we answer this, we need to take a look at ISO-32000-1.
In section 7.7.3.3Page Objects, you'll find the description of UserUnit in Table 30, "Entries in a page object":
(Optional; PDF 1.6) A positive number that shall give the size of
default user space units, in multiples of 1⁄72 inch. The range of
supported values shall be implementation-dependent. Default value: 1.0
(user space unit is 1⁄72 inch).
This key was introduced in PDF 1.6; you won't find it in older files. It's optional, so you won't always find it in every page dictionary. In my book, I also explain that the maximum value of the UserUnit key is 75,000.
Now how to retrieve this value with iTextSharp?
You already have Rectangle dim = reader.GetPageSize(i); which returns the MediaBox. This may not be the size of the visual part of the page. If there's a CropBox defined for the page, viewers will show a much smaller size than what you have in xy (but you probably knew that already).
What you need now is the page dictionary, so that you can retrieve the value of the UserUnit key:
PdfDictionary pageDict = reader.GetPageN(i);
PdfNumber userUnit = pageDict.GetAsNumber(PdfName.USERUNIT);
Most of the times userUnit will be null, but if it isn't you can use userUnit.FloatValue.