HomeProjectsContactGitHub

1D & 2D Barcodes

Repository

I created this project in order to gain more experience with the NextJS framework. With this web app you can generate different types of 1 and 2 dimensional barcodes, such as QR Codes, EAN-13 Codes, Code 128 codes or Data Matrix. This web app also allows you to to scan your previously generated codes and other codes. For the styling of the web app I chose the Tailwind CSS library for inline styling and in general shortened styling.

Barcode Component

This React component takes in props and based off of these props it generates a barcode. With the prop chosenOption you can define what type of code you want. The prop value defines the content of the barcode. To generate the barcodes I used the bwipjs library. At the end, this component returns either the successfully rendered barcode or an error message.

1interface BarCodeProps {
2    chosenOption: string;
3    value: string;
4    onRendered?: (canvas: HTMLCanvasElement) => void;
5}
6
7export default function BarCode({chosenOption, value, onRendered}: BarCodeProps) {
8    const canvasRef = useRef<HTMLCanvasElement>(null);
9    const [error, setError] = useState<string | null>(null);
10
11    useEffect(() => {
12        setError(null);
13        if (!canvasRef.current) return;
14
15        try {
16            bwipjs.toCanvas(canvasRef.current, {
17                bcid: chosenOption,
18                text: value,
19                scale: 3,
20                includetext: true,
21                textxalign: 'center',
22            });
23            if (onRendered) {
24                onRendered(canvasRef.current);
25            }
26        } catch (e: any) {
27            console.error("Barcode generation error:", e);
28            setError(e.message || 'Failed to generate barcode.');
29        }
30    }, [value, chosenOption, onRendered])
31
32    return (
33        <div className="w-full h-auto border rounded-lg p-4 bg-white flex items-center justify-center">
34            {error ? (
35                <p className="text-red-500 text-center text-sm font-medium">{error}</p>
36            ) : (
37                <canvas ref={canvasRef} className="w-full h-auto" />
38            )}
39        </div>
40    );
41}

getCameraStream()

This function is part of my Camera component. It creates a visual input field for the camera, captures the content of the video feed and then decodes the barcode. For the decoding of the barcode I use the popular @zxing multi code reader library. If the camera decodes successfully, it sets the value of the barcode, if not, it will return a detailed error message which also shows what kind of error.

1const codeReader = new BrowserMultiFormatReader();
2let active = true;
3
4const getCameraStream = async () => {
5  try {
6    console.log("Requesting camera access...");
7
8    const constraints = {
9      audio: false,
10      video: {
11        facingMode: { ideal: "environment" },
12        width: { min: 640, ideal: 1280, max: 1920 },
13        height: { min: 480, ideal: 720, max: 1080 },
14        frameRate: { ideal: 30 },
15      },
16    };
17
18    let videoStream;
19    try {
20      videoStream = await navigator.mediaDevices.getUserMedia(constraints);
21    } catch (idealError) {
22      console.log("Ideal constraints failed, trying more relaxed constraints");
23      videoStream = await navigator.mediaDevices.getUserMedia({
24        audio: false,
25        video: {
26          facingMode: "environment",
27          width: { min: 320, ideal: 640 },
28          height: { min: 240, ideal: 480 },
29        },
30      });
31    }
32
33    console.log("Camera stream obtained:", videoStream);
34    setHasPermission(true);
35
36    if (videoRef.current) {
37      videoRef.current.srcObject = videoStream;
38
39      codeReader.decodeFromVideoDevice(
40        null,
41        videoRef.current,
42        (result, err) => {
43          if (active && result) {
44            console.log("Barcode detected:", result.getText());
45            setBarcode(result.getText());
46          }
47        },
48      );
49    }
50  } catch (e: any) {
51    console.error("Camera access failed:", e.name, e.message);
52    setError(`Camera access failed: ${e.name}${e.message}`);
53
54    if (e.name === "NotAllowedError") {
55      setError("Please allow camera access in your browser settings");
56    } else if (
57      e.name === "NotFoundError" ||
58      e.name === "OverconstrainedError"
59    ) {
60      setError("No suitable camera found. Please try with a different device.");
61    } else {
62      setError("Failed to access camera: " + e.message);
63    }
64  }
65};

Live Demonstration

Live Demo

You can try the web app yourself by clicking on the button. You will need to allow camera access on the reader. From personal experience I noticed the web app does not always work on Android devices.

Video Demonstration

This video requires optional cookies (YouTube).