Engee documentation
Notebook

Barcode generation and decoding

In this article, we will examine in detail the possibilities of converting a string of characters into a black-and-white barcode (as an image) and vice versa. The code uses a package Images for working with images.

The program we have implemented consists of two main functions:

  1. string_to_barcode – converts a string into a barcode image;
  2. barcode_to_string – Decodes the barcode image back into a string.
In [ ]:
using Images

The string_to_barcode function

The logic of the work

  1. Initialization of an empty bits array: it stores the bits of all characters of the string.

  2. Loop over each character of the string:

    • bitstring(UInt8(char)) converts a character to its 8-bit representation,
    • parse(Int, bit) converts each bit to the corresponding integer,
    • append! adds these numbers to the array bits.
  3. Creating a two-dimensional array for an image:

    • bits' transposes a vector of bits (converts to a string),
    • repeat repeats this line length(bits)/2 once to create a two-dimensional array (image) where each row is identical,
    • the coefficient length(bits)/2 selected to create a rectangular image.
  4. Result return: The function returns a two-dimensional array of 0 and 1, which can be interpreted as a black and white image.

In [ ]:
function string_to_barcode(s::String)
    bits = []
    for char in s
        binary_str = bitstring(UInt8(char)) # Получаем бинарное представление символа (8 бит)
        append!(bits, [parse(Int, bit) for bit in binary_str]) # Преобразуем каждый бит в число и добавляем в вектор
    end
    repeated_bits = repeat(bits', Int.(length(bits)/2),1) # Повторяем вектор бит
    return repeated_bits
end
Out[0]:
string_to_barcode (generic function with 1 method)

Usage example:

In [ ]:
barcode = string_to_barcode("_Engee_") # Переводим строку в битовое представление
img = Gray.(barcode) # Преобразуем в изображение
display(img) # Показываем изображение
save("barcode.png", img) # Сохраняем в файл
No description has been provided for this image

The barcode_to_string function

The logic of the work

  1. Image binarization:

    • Gray.(img) converts an image to shades of gray;
    • .> 0.5 converts to pure black and white (values greater than 0.5 become 1, the rest become 0).
  2. Extracting the bit sequence:

    • binary_img[10, :] it takes the 10th line of the image (you can use any one, since all the lines are the same).
  3. Character decoding:

  • the cycle goes through bits in 8 increments (each character is encoded with 8 bits),
  • for every 8 bits
    • reduce((x, y) -> x * 2 + y, byte) converts an array of bits to a number,
    • Char() converts the number to the corresponding character.
  1. Line Assembly:
    • join(chars) combines all characters into a single string.
In [ ]:
function barcode_to_string(img)
    binary_img = Gray.(img) .> 0.5 # Преобразуем изображение в бинарный формат (0 или 1)
    bits = binary_img[10, :] # Получаем первую строку изображения (так как все строки одинаковы)
    # Преобразуем биты в символы
    chars = []
    for i in 1:8:length(bits)
        # Берем 8 бит и преобразуем их в символ
        byte = bits[i:i+7]
        char = Char(reduce((x, y) -> x * 2 + y, byte))
        push!(chars, char)
    end
    # Собираем символы в строку
    return join(chars)
end
Out[0]:
barcode_to_string (generic function with 1 method)

Usage example:

In [ ]:
img = load("barcode.png") # Загружаем изображение штрихкода
display(img) # Показываем изображение
decoded_string = barcode_to_string(img) # Декодируем строку
println("Decoded string: ", decoded_string) # Выводим результат
No description has been provided for this image
Decoded string: _Engee_

Conclusion

This code demonstrates the basic principle of converting a string to a visual representation and vice versa. This principle can be extended to more complex use cases.

It is also worth mentioning some implementation features.

  1. Character encoding: Each character is encoded with exactly 8 bits (ASCII), which limits the character set but simplifies implementation.

  2. Visual representation: A barcode is created by repeating the same bit sequence in several lines, which makes it more visible.

  3. Stability: When decoding, a specific image string (the 10th) is taken, which makes the algorithm vulnerable to image corruption. In real systems, more complex recovery logic is usually used.