Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
0da56fd
doc: Update README
OUDON Jun 24, 2022
bf16068
doc: Update README
OUDON Jun 25, 2022
34c4281
doc: Update README
OUDON Jun 25, 2022
bf99422
doc: Update README
OUDON Jun 25, 2022
636dea6
add `get_ndarray`
Ar-Ray-code Jul 24, 2022
1f84d09
Merge pull request #12 from Ar-Ray-code/features/np
OUDON Jul 26, 2022
b26089e
doc: Create CONTRIBUTING.md
OUDON Jul 27, 2022
a360985
doc: Update README.md
OUDON Jul 27, 2022
d7c70d9
feat: Use numpy only when numpy and cv2 are installed
OUDON Jul 27, 2022
37c3362
doc: Update CONTRIBUTING.md
OUDON Jul 28, 2022
a4734c2
ci: Setup linter
OUDON Jul 28, 2022
30541e1
ci: Exclude generator_polynomials.py from the lint targets
OUDON Jul 28, 2022
a5ffd9d
refactor: Run formatter
OUDON Jul 28, 2022
8442b96
ci: Run make lint in the python-app workflow
OUDON Jul 28, 2022
69dff27
ci: flake8
OUDON Jul 28, 2022
81adf74
ci: Use profile=black in isrot
OUDON Jul 28, 2022
a376f52
ci: install with the dev extra
OUDON Jul 28, 2022
1f8b5d4
doc: Update CONTRIBUTING.md
OUDON Jul 28, 2022
3f9ef19
chore: Change CONTRIBUTING.md
OUDON Jul 28, 2022
7b8b325
chore: Add trailing new line
OUDON Jul 28, 2022
afdc6c3
chore: Add trailing new line
OUDON Jul 28, 2022
9fcfe1b
Merge pull request #13 from OUDON/ci/add-linter
OUDON Jul 28, 2022
aa696a9
ci: Create dependabot.yml
OUDON Jul 28, 2022
68392b3
doc: Update the references in the README.md
OUDON Aug 3, 2022
56592fb
feat: Add the option `with_quiet_zone` into rMQR#to_list and rMQR#__s…
OUDON Aug 4, 2022
36a7c66
chore: make format
OUDON Aug 4, 2022
fbb9015
refactor: Use with-quiet-zone in QRIMage#_make_image
OUDON Aug 4, 2022
fb962fb
chore: make format
OUDON Aug 4, 2022
3bd7b10
chore: Remove unused import
OUDON Aug 4, 2022
09b11e4
Merge pull request #16 from OUDON/feat/add-with-quiet-zone
OUDON Aug 4, 2022
4570628
doc: Update README.md
OUDON Aug 5, 2022
efad495
wip: Add docstrings
OUDON Aug 6, 2022
6a3d79e
Update README.md
OUDON Aug 6, 2022
c9be13c
doc: Add docstrings to src/rmqrcode/rmqrcode.py
OUDON Aug 9, 2022
a6c5467
chore: make format
OUDON Aug 9, 2022
cebe1be
Merge pull request #19 from OUDON/doc/docstrings
OUDON Aug 10, 2022
11c2d7e
chore: Bumps to v1.2.0
OUDON Aug 10, 2022
80a5572
Merge branch 'develop' of github.com:OUDON/rmqr-generator into develop
OUDON Aug 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "pip" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
10 changes: 3 additions & 7 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,11 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest
pip install .
pip install .[dev]
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
- name: Lint
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
make lint
- name: Test with pytest
run: |
python -m pytest
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Contributing to rmqrcode-python
Thank you for interesting in contributing to rmqrcode-python! Any suggestions are welcome.

## Style Guides

### Docstrings
This project uses [Google-Style format](https://google.github.io/styleguide/pyguide.html#381-docstrings) docstrings.

### Git Commit Message
Consider starting commit message with one of the following prefixes.
- `feat:` : New feature
- `fix:` : Bug fix
- `refactor:` : Refactoring
- `chore:` : Little things
- `ci`: CI
- `doc:` : Documentation

## Pull Requests
Before make a pull request, please do the following.
1. `make format`
2. `make lint`
3. `python -m pytest` and make sure all tests are passed.
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: lint
lint:
flake8 src
isort --check --diff src
black --check src

.PHONY: format
format:
isort src
black src
27 changes: 23 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
![reop-url](https://user-images.githubusercontent.com/14174940/172978619-accbf9d0-9dd8-4b19-b47e-ad139a68dcc9.png)


This is an rMQR Code image generator implemented in Python. This is implemented based on [ISO/IEC 23941:2022](https://www.iso.org/standard/77404.html).
The rMQR Code is a rectangular two-dimensional barcode. This package can generate an rMQR Code image. This is implemented based on [ISO/IEC 23941: Rectangular Micro QR Code (rMQR) bar code symbology specification](https://www.iso.org/standard/77404.html).

[![pytest](https://github.com/OUDON/rmqrcode-python/actions/workflows/python-app.yml/badge.svg?branch=main)](https://github.com/OUDON/rmqrcode-python/actions/workflows/python-app.yml)
![PyPI](https://img.shields.io/pypi/v/rmqrcode?color=blue)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/rmqrcode)
![PyPI - Downloads](https://img.shields.io/pypi/dm/rmqrcode?color=orange)

## 📌 Important Notice
## 🎮 Online Demo Site
You can try this online: https://rmqr.oudon.xyz .

## 📌 Notice
- Please verify an image generated by this software whether it can decode correctly before use.
- Because this is in early stage, QR Code readers may have not been supported rMQR Code yet.


## 🚀 Installation
```
pip install rmqrcode
Expand Down Expand Up @@ -64,7 +72,7 @@ The `fit_strategy` parameter is enum value of `rmqrcode.FitStrategy` to specify
- **`FitStrategy.BALANCED`**: Try to keep balance of width and height.

Here is an example of images genereated by each fit strategies for data `Test test test`:
![Example of fit strategies](https://user-images.githubusercontent.com/14174940/172822478-4f2b5fb8-49bd-464f-b6b2-c7347f71cbf5.png)
![Example of fit strategies](https://user-images.githubusercontent.com/14174940/175759120-7fb5ec71-c258-4646-9b91-6865b3eeac3f.png)

### Save as image
```py
Expand All @@ -76,7 +84,7 @@ image.save("my_qr.png")
```


## 📚 Advanced Usage
## 📙 Advanced Usage
### Select rMQR Code size manually
To select rMQR Code size manually, use `rMQR()` constructor.
```py
Expand Down Expand Up @@ -108,6 +116,17 @@ The rMQR Code has the four encoding modes Numeric, Alphanumeric, Byte and Kanji
|Byte|✅|
|Kanji||


## 🤝 Contiributing
Any suggestions are welcome! If you are interesting in contiributing, please read [CONTRIBUTING](https://github.com/OUDON/rmqrcode-python/blob/develop/CONTRIBUTING.md).


## 📚 References
- [Rectangular Micro QR Code (rMQR) bar code symbology specification: ISO/IEC 23941](https://www.iso.org/standard/77404.html)
- [rMQR Code | QRcode.com | DENSO WAVE](https://www.qrcode.com/en/codes/rmqr.html)
- [Creating a QR Code step by step](https://www.nayuki.io/page/creating-a-qr-code-step-by-step)


----
The word "QR Code" is registered trademark of DENSO WAVE Incorporated.<br>
http://www.denso-wave.com/qrcode/faqpatent-e.html
15 changes: 15 additions & 0 deletions example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
import logging


try:
import numpy
import cv2
USE_NUMPY = True
except ImportError:
USE_NUMPY = False


def main():
data = "https://oudon.xyz"
error_correction_level = ErrorCorrectionLevel.M
Expand All @@ -26,6 +34,13 @@ def main():
image.show()
image.save("my_qr.png")

# Convert to numpy array
if USE_NUMPY:
img = image.get_ndarray()
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()


def _init_logger():
logger = logging.getLogger()
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
build-backend = "setuptools.build_meta"

[tool.black]
line-length = 119
exclude = "generator_polynomials.py"
15 changes: 13 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = rmqrcode
version = 0.1.3
version = 0.2.0
author = Takahiro Tomita
author_email = ttp8101@gmail.com
description = An rMQR Code Generetor
Expand All @@ -23,10 +23,21 @@ install_requires =
[options.extras_require]
dev =
pytest
flake8
isort
black

[options.packages.find]
where = src

[options.entry_points]
console_scripts =
rmqr = rmqrcode.console:main
rmqr = rmqrcode.console:main

[flake8]
max-line-length = 119
extend-ignore = E203
exclude = src/rmqrcode/format/generator_polynomials.py

[isort]
profile=black
9 changes: 4 additions & 5 deletions src/rmqrcode/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from .rmqrcode import rMQR
from .rmqrcode import FitStrategy
from .rmqrcode import DataTooLongError
from .rmqrcode import IllegalVersionError
from .format.error_correction_level import ErrorCorrectionLevel
from .qr_image import QRImage
from .format.error_correction_level import ErrorCorrectionLevel
from .rmqrcode import DataTooLongError, FitStrategy, IllegalVersionError, rMQR

__all__ = ("rMQR", "DataTooLongError", "FitStrategy", "IllegalVersionError", "QRImage", "ErrorCorrectionLevel")
54 changes: 28 additions & 26 deletions src/rmqrcode/console.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
#!/usr/bin/env python
import rmqrcode
from rmqrcode import rMQR
from rmqrcode import QRImage
from rmqrcode import ErrorCorrectionLevel
from rmqrcode import FitStrategy
from rmqrcode import DataTooLongError
from rmqrcode import IllegalVersionError

import argparse
import sys

from rmqrcode import (
DataTooLongError,
ErrorCorrectionLevel,
FitStrategy,
IllegalVersionError,
QRImage,
rMQR,
)


def _show_error_and_exit(msg):
print(msg, file=sys.stderr)
sys.exit(1)


def _make_qr(data, ecc, version, fit_strategy):
if version == None:
if version is None:
qr = rMQR.fit(data, ecc=ecc, fit_strategy=fit_strategy)
else:
try:
Expand All @@ -29,7 +30,6 @@ def _make_qr(data, ecc, version, fit_strategy):
return qr



def _save_image(qr, output):
image = QRImage(qr)
try:
Expand All @@ -42,24 +42,19 @@ def main():
parser = _init_argparser()
args = parser.parse_args()

if args.ecc == 'M':
if args.ecc == "M":
ecc = ErrorCorrectionLevel.M
elif args.ecc == 'H':
elif args.ecc == "H":
ecc = ErrorCorrectionLevel.H

fit_strategy = FitStrategy.BALANCED
if args.fit_strategy == 'min_width':
if args.fit_strategy == "min_width":
fit_strategy = FitStrategy.MINIMIZE_WIDTH
elif args.fit_strategy == 'min_height':
elif args.fit_strategy == "min_height":
fit_strategy = FitStrategy.MINIMIZE_HEIGHT

try:
qr = _make_qr(
args.DATA,
ecc=ecc,
version=args.version,
fit_strategy=fit_strategy
)
qr = _make_qr(args.DATA, ecc=ecc, version=args.version, fit_strategy=fit_strategy)
except DataTooLongError:
_show_error_and_exit("Error: The data is too long.")

Expand All @@ -68,13 +63,20 @@ def main():

def _init_argparser():
parser = argparse.ArgumentParser()
parser.add_argument('DATA', type=str, help="Data to encode.")
parser.add_argument('OUTPUT', type=str, help="Output file path")
parser.add_argument('--ecc', help="Error correction level. (default: M)", type=str, choices=["M", "H"], default='M')
parser.add_argument('--version', help="rMQR Code version like 'R11x139'.")
parser.add_argument('--fit-strategy', choices=["min_width", "min_height", "balanced"], help="Strategy how to determine rMQR Code size.", dest="fit_strategy")
parser.add_argument("DATA", type=str, help="Data to encode.")
parser.add_argument("OUTPUT", type=str, help="Output file path")
parser.add_argument(
"--ecc", help="Error correction level. (default: M)", type=str, choices=["M", "H"], default="M"
)
parser.add_argument("--version", help="rMQR Code version like 'R11x139'.")
parser.add_argument(
"--fit-strategy",
choices=["min_width", "min_height", "balanced"],
help="Strategy how to determine rMQR Code size.",
dest="fit_strategy",
)
return parser


if __name__ == "__main__":
main()
main()
6 changes: 2 additions & 4 deletions src/rmqrcode/encoder/byte_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ class ByteEncoder:
@staticmethod
def _encoded_bits(s):
res = ""
encoded = s.encode('utf-8')
encoded = s.encode("utf-8")
for byte in encoded:
res += bin(byte)[2:].zfill(8)
return res


@staticmethod
def encode(data, character_count_length):
res = ByteEncoder.MODE_INDICATOR
res += bin(len(data))[2:].zfill(character_count_length)
res += ByteEncoder._encoded_bits(data)
return res


@staticmethod
def length(data):
return len(data.encode('utf-8'))
return len(data.encode("utf-8"))
3 changes: 2 additions & 1 deletion src/rmqrcode/enums/color.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from enum import Enum


class Color(Enum):
UNDEFINED = -1
WHITE = 0
BLACK = 1
BLACK = 1
3 changes: 2 additions & 1 deletion src/rmqrcode/enums/fit_strategy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from enum import Enum


class FitStrategy(Enum):
MINIMIZE_WIDTH = 0
MINIMIZE_HEIGHT = 1
BALANCED = 2
BALANCED = 2
2 changes: 1 addition & 1 deletion src/rmqrcode/format/alignment_pattern_coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
77: [25, 51],
99: [23, 49, 75],
139: [27, 55, 83, 111],
}
}
Loading