{ "cells": [ { "cell_type": "markdown", "id": "7d664cee-d509-456f-93d1-cc8db51003aa", "metadata": {}, "source": [ "### Playing with GS1_128 Barcodes, and QRCode\n", "\n", "This shall be usefull in any company\n", "- needed:\n", " - for the GUI: Python \"de base\", Jupyterlab or Jupyterlite\n", " - to print GS1_128 clean BarCodes: \n", " - libraries : pip install python-barcode\n", " - a workaround to get a proper gs1_ean128: below 'def Ean128legend()'\n", "- to print QRcode:\n", " - libraries : pip install qrcode\n", "- to read QRcode via camera: (but example not working on Jupyterlite yet)\n", " - libraries : pip install opencv-python\n", " " ] }, { "cell_type": "code", "execution_count": null, "id": "444d1ab7-3cec-461e-8aa0-5de218bac46d", "metadata": { "tags": [] }, "outputs": [], "source": [ "try:\n", " # if on Jupyterlite\n", " import micropip\n", " await micropip.install(\"python-barcode\")\n", " await micropip.install(\"qrcode\")\n", " # opencv is in standard included in Jupyterlite\n", "except:\n", " pass" ] }, { "cell_type": "code", "execution_count": null, "id": "8d2b810b-1c96-4750-bdef-6c858712a9d3", "metadata": { "tags": [] }, "outputs": [], "source": [ "import barcode # python-barcode\n", "barcode.PROVIDED_BARCODES" ] }, { "cell_type": "code", "execution_count": null, "id": "93b663a3-81a7-478f-a46b-8ca61d000680", "metadata": { "tags": [] }, "outputs": [], "source": [ "from barcode import EAN13" ] }, { "cell_type": "code", "execution_count": null, "id": "3fed8f95-123b-4751-9a45-97a824eb0219", "metadata": { "tags": [] }, "outputs": [], "source": [ "from barcode.writer import ImageWriter\n", "from IPython.display import SVG, display" ] }, { "cell_type": "code", "execution_count": null, "id": "3ae1fd23-7dee-40e4-bd4c-dac362eee076", "metadata": { "tags": [] }, "outputs": [], "source": [ "EAN = barcode.get_barcode_class('ean13')" ] }, { "cell_type": "code", "execution_count": null, "id": "77a74c34-11df-4ee9-9ef7-4bcb17643d98", "metadata": { "tags": [] }, "outputs": [], "source": [ "ean = barcode.get('ean13', '123456789102')" ] }, { "cell_type": "code", "execution_count": null, "id": "a93ef229-2cf5-4695-b006-52ea3317b707", "metadata": { "tags": [] }, "outputs": [], "source": [ "ean.get_fullcode()" ] }, { "cell_type": "code", "execution_count": null, "id": "de919f26-f579-459e-936c-f0b68959d452", "metadata": { "tags": [] }, "outputs": [], "source": [ "my_ean = EAN('5901234123457')" ] }, { "cell_type": "code", "execution_count": null, "id": "14dc3350-7615-423b-af70-e8939a5c9d87", "metadata": { "tags": [] }, "outputs": [], "source": [ "fullname = my_ean.save('ean13_barcode')" ] }, { "cell_type": "code", "execution_count": null, "id": "9dc05ee9-ae91-4650-bf8a-45762c45f596", "metadata": { "tags": [] }, "outputs": [], "source": [ "display(SVG(fullname))" ] }, { "cell_type": "code", "execution_count": null, "id": "a8f28bf6-c1df-489e-8214-96c339c20fef", "metadata": { "tags": [] }, "outputs": [], "source": [ "gs1_128 = barcode.get_barcode_class('gs1_128')\n", "my_gs1 = gs1_128(\"00123456789012345675\")" ] }, { "cell_type": "code", "execution_count": null, "id": "9db6cfa5-9d34-4ccd-bce0-bddafc8e4e45", "metadata": { "tags": [] }, "outputs": [], "source": [ "fullname = my_gs1.save('gs1_barcode')\n", "display(SVG(fullname))" ] }, { "cell_type": "code", "execution_count": null, "id": "2b3afce1-6206-44b2-a33a-1082c847be9f", "metadata": { "tags": [] }, "outputs": [], "source": [ "def Ean128legend(chaine_in, with_spacing= True,print_error=False):\n", " \"\"\"Transform a given gs1_128 barecode string into it's barcode legend\n", " or or '\\xf1' string can be used to specify a (FNC1)\n", " example: Ean128legend('10ABCD15220412')\n", " will give: '(10)ABCD(15)220412' \"\"\"\n", "\n", " # special characters:\n", " # on Grand Zebu XL: fc1num = int(207); fc1 = chr(fc1num)\n", " # car(241) for python_barcode, while grandzebu Code128-v2.0 is 207\n", " fnc1 = fc1 = '\\xf1' \n", " \n", " #gs1 = list of (application identifiers possible , associated maximum length)\n", " # 'x' convention is for any digit\n", " gs1=[('00', 18),('01', 14),('02', 14),('10', 20),('1x', 6),('20', 2),\n", " ('21', 20),('22', 20),('235', 28),('240', 30),('241', 30),('242', 6),('243', 20),\n", " ('250', 30),('251', 30),('253', 30),('254', 20),('255',25),\n", " ('30', 8),\n", " ('310x', 6),('311x', 6),('312x', 6),('313x', 6),('314x', 6),('315x', 6),('316x', 6),\n", " ('32xx', 6),('33xx', 6),('34xx', 6),('35xx', 6),('36xx', 6),\n", " ('37', 8),\n", " ('390x', 15),('391x', 18),('392x', 15),('393x', 18),('394x', 4),('395x', 6),\n", " ('400', 30),('401', 30),('402', 17),('403', 30),\n", " ('41x', 13),('420', 20),('421', 12),('422', 3),('423', 15),('424', 3),('425', 15),('426', 3),('427', 3),\n", " ('4300', 35),('4301', 35),('4307', 2),('430x', 70),\n", " ('4310', 35),('4311', 35),('4317', 2),('4318', 20),('431x', 70),\n", " ('4320', 35),('4321', 1),('4322', 1),('4323', 1),('4324', 10),('4325', 10),('4326', 6),\n", " ('7001', 13),('7002', 30),('7003', 10),('7004', 4),('7005', 12),('7006', 6),('7007', 12),('7008', 3),('7009', 14),\n", " ('7010', 2),('7011', 10),\n", " ('7020', 20),('7021', 20),('7022', 20),('7023', 30),\n", " ('703x', 30),('7040', 4),('71x', 20),('723x', 30),('7240', 20),\n", " ('8001', 14),('8002', 20),('8003', 30),('8004', 30),('8005', 6),('8006', 18),\n", " ('8008', 12),('8009', 50),('8010', 30),('8011', 12),('8012', 20),('8013', 25),('8017', 18),\n", " ('8018', 18),('8019', 10),('8020', 25),('8026', 18),('8110', 70),('81111', 4),('81112', 70),\n", " ('90', 30),('9x', 90),]\n", " gs1_ai = dict(set(gs1))\n", "\n", " # val_res = list of (application identifier, values) found\n", " val_res = []\n", " errors = \"\"\n", "\n", "\n", "\n", " #Action 1 : REPLACE \"\" or \"\" strings per fc1 character\n", " chaine = chaine_in + \"\"\n", " chaine=chaine.replace(\"\", fnc1)\n", " chaine=chaine.replace(\"\", fnc1)\n", "\n", " w = i = int(1)\n", " ai_res = \"\"\n", " # itertee on all character of the given barcode\n", " while w <= len(chaine):\n", " #in case a FC1 is seen\n", " if chaine[w - int(1)] == fc1:\n", " if ai_res !=\"\" and print_error == True:\n", " errors += ai_res + \" \"\n", " ai_res = \"\"\n", " else:\n", " #feeding ai_res with start of next rubrick token, character per character\n", " ai_res += chaine[w - int(1)] + \"\"\n", "\n", " #search if ai_res[i] has now a matching ai identifier\n", " ai_found = ''\n", " for k in range(0 , len(ai_res) ):\n", " ai_look = ai_res[:len(ai_res)-k]+\"xxxx\"[:k]\n", " if ai_look in gs1_ai and ai_res.isdigit(): ## a match !\n", " ai_found = ai_look\n", " # print(f'a match:({ai_found}: {gs1_ai[ai_found]:2d})')\n", " break\n", "\n", " # if an Application_Identifier has been found, get the Application Identifier value\n", " if ai_found != '':\n", " # Application Identifier value is:\n", " # - limited per next or remaining characters of the string\n", " # - and its maximal authorised lenght\n", " forward_value = \"\" + chaine[w:].split(fc1)[0]\n", " truncated_value = forward_value[:gs1_ai[ai_found]]\n", " if with_spacing and ai_res == '00':\n", " truncated_value=truncated_value[0]+\" \"+truncated_value[1:8]+\" \"+truncated_value[8:17]+\" \"+truncated_value[17] \n", " val_res = val_res +[( ai_res, truncated_value)]\n", " ai_res = \"\"\n", " # position w at the last character utilised\n", " w = w + len(truncated_value)\n", " w += int(1)\n", "\n", " errors += ai_res + \" \"\n", " if errors.strip() != \"\" and print_error == True:\n", " print(\"un-traducted\", errors , \" in \" , chaine_in )\n", " legend = \"\".join([\"(\"+ k[0] + \")\"+k[1] for k in val_res])\n", " return legend\n" ] }, { "cell_type": "code", "execution_count": null, "id": "9c0ad619-9d3c-4f5b-9598-ef2b4277de22", "metadata": { "tags": [] }, "outputs": [], "source": [ "def eancheck(chaine_in, raise_error=0):\n", " \"returns the string with the correct last key\"\n", " result = \"\"\n", " if len(chaine_in.strip()) <= 1:\n", " return result\n", " chaine = chaine_in.strip()\n", " for i in range(len(chaine) ):\n", " if not chaine[i].isdigit():\n", " result = \"not with digits only\"\n", " return result\n", " x = \"\"\n", " checksum = 0\n", " chaineHorsCle = chaine[:-1]\n", " for i in range(0, len(chaineHorsCle), 2):\n", " checksum += int(chaineHorsCle[len(chaineHorsCle) - i - 1])\n", " x += chaineHorsCle[len(chaineHorsCle) - i - 1]\n", " checksum *= 3\n", " for i in range(1, len(chaineHorsCle), 2):\n", " checksum += int(chaineHorsCle[len(chaineHorsCle) - i - 1])\n", " result = chaineHorsCle + str((10 - checksum % 10) % 10)\n", " if raise_error > 0:\n", " if result != chaine:\n", " result = chaine + \" has an error of key : \" + chaine[-1] + \" instead of \" + str((10 - checksum % 10) % 10)\n", " return result\n", "\n", "def eansscc(chaine_in):\n", " \"compute a correct sscc\"\n", " chaine = chaine_in + \"\"\n", " if not chaine.strip().isdigit():\n", " result = \"not with digits only\"\n", " elif len(chaine) > 18:\n", " result = \"error : more than 17 digits\"\n", " else:\n", " # increase to 17 and return with the key\n", " chain_at_length = (\"000000000000000000\" + chaine_in)[-17:]\n", " result = eankey(chain_at_length)\n", " return result\n", " \n", "\n", "def eankey(chaine_in):\n", " \"complet the key with a digit\"\n", " return eancheck((chaine_in + \" \").strip() + \"*\")" ] }, { "cell_type": "code", "execution_count": null, "id": "3ffeaa8b-22ae-4fec-9f79-19ab50815d3b", "metadata": { "tags": [] }, "outputs": [], "source": [ "z=\"00123456789012345675\"\n", "my_gs1 = gs1_128(z)\n", "options=dict(font_size = 10, module_width=0.4)\n", "filename = ean.save('ean13g',options, text=Ean128legend(z, True))\n", "display(SVG(filename))" ] }, { "cell_type": "code", "execution_count": null, "id": "1ad1b0f1-dba5-4cd0-b976-759f2d9be40f", "metadata": { "tags": [] }, "outputs": [], "source": [ " print('Ean128legend', Ean128legend(\"10ABCD15220412\", True))\n", " print('Ean128legend', Ean128legend(\"00\"+eansscc(\"12345678901234567\")))\n", " print('Ean128legend', Ean128legend(\"0012345678901234567\"+\"5\"))\n", " print('Ean128legend', Ean128legend(\"3712200015220412\"))\n", " print('eancheck', eancheck(\"04012345678900\", 1))\n", " print('eansscc', eansscc(\"39521100100130012\"))" ] }, { "cell_type": "code", "execution_count": null, "id": "401ac364-09b4-46c7-ae16-e5c34be38808", "metadata": { "tags": [] }, "outputs": [], "source": [ "gs1_128 = barcode.get_barcode_class('gs1_128')\n", "my_gs1 = gs1_128(\"10ABCD\"+'\\xf1'+\"15220412\")" ] }, { "cell_type": "code", "execution_count": null, "id": "7274a344-7c26-4b55-b835-1eff99e2ab44", "metadata": { "tags": [] }, "outputs": [], "source": [ "options=dict(font_size=12)\n", "filename = ean.save('ean13g',options, text=Ean128legend(\"10ABCD\"+'\\xf1'+\"15220412\", True))" ] }, { "cell_type": "code", "execution_count": null, "id": "11348340-a3a7-45b2-b031-47d2cf4e216b", "metadata": { "tags": [] }, "outputs": [], "source": [ "display(SVG(filename))" ] }, { "cell_type": "markdown", "id": "4a61b61a-229c-4d4e-89db-a34c04d5576a", "metadata": {}, "source": [ "### from base.py\n", "default_writer_options = {\n", " \"module_width\": 0.2,\n", " \"module_height\": 15.0,\n", " \"quiet_zone\": 6.5,\n", " \"font_size\": 10,\n", " \"text_distance\": 5.0,\n", " \"background\": \"white\",\n", " \"foreground\": \"black\",\n", " \"write_text\": True,\n", " \"text\": \"\",\n", " }" ] }, { "cell_type": "code", "execution_count": null, "id": "12b464b0-9150-4498-8e56-250f65d7467d", "metadata": { "tags": [] }, "outputs": [], "source": [ "z=\"3712200015220412\"\n", "my_gs1 = gs1_128(z)\n", "options=dict(font_size = 10, module_width=0.4)\n", "filename = ean.save('ean13g',options, text=Ean128legend(z, True))\n", "display(SVG(filename))" ] }, { "cell_type": "code", "execution_count": null, "id": "c129f1e5-1ac3-4560-b846-298f84787a9d", "metadata": { "tags": [] }, "outputs": [], "source": [ "import qrcode\n", "from IPython.display import Image, display\n", "img = qrcode.make('artisou à croûte')\n", "img.save(\"test.png\")\n", "display(Image(filename='test.png'))\n" ] }, { "cell_type": "code", "execution_count": null, "id": "77952adc-b07d-4899-8d36-9fe08511e243", "metadata": { "tags": [] }, "outputs": [], "source": [ "# reading QRcode via jupyterlab\n", "# for Jupyterlite, there must be a missing detail \n", "# . POC there must be a way: https://github.com/holoviz/panel/blob/main/examples/gallery/streaming_videostream.ipynb\n", "# import the opencv library\n", "import cv2\n", "\n", "# define a video capture object\n", "vid = cv2.VideoCapture(0)\n", "\n", "detector = cv2.QRCodeDetector()\n", "\n", "while True:\n", "\n", " # Capture the video frame by frame\n", " ret, frame = vid.read()\n", "\n", " data, bbox, straight_qrcode = detector.detectAndDecode(frame)\n", " if len(data) > 0:\n", " print(data)\n", "\n", " # Display the resulting frameq\n", " cv2.imshow('frame', frame)\n", "\n", " # the 'q' button is set as the\n", " # quitting button you may use any\n", " # desired button of your choice\n", " if cv2.waitKey(1) & 0xFF == ord('q'):\n", " break\n", "\n", "# After the loop release the cap object\n", "vid.release()\n", "# Destroy all the windows\n", "cv2.destroyAllWindows()" ] }, { "cell_type": "code", "execution_count": null, "id": "62941f6b-eb96-4c0c-b33f-6d843946a8cd", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.11" } }, "nbformat": 4, "nbformat_minor": 5 }