diff --git a/files/initrd/opt/rr/boot.sh b/files/initrd/opt/rr/boot.sh index ef5979ef..9853438a 100755 --- a/files/initrd/opt/rr/boot.sh +++ b/files/initrd/opt/rr/boot.sh @@ -249,8 +249,11 @@ else if [ "${DSMLOGO}" = "true" -a -c "/dev/fb0" ]; then IP="$(getIP)" [ -n "${IP}" ] && URL="http://${IP}:5000" || URL="http://find.synology.com/" - python ${WORK_PATH}/include/functions.py makeqr -d "${URL}" -l "br" -o "${TMP_PATH}/qrcode.png" - [ -f "${TMP_PATH}/qrcode.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode.png" >/dev/null 2>/dev/null || true + python ${WORK_PATH}/include/functions.py makeqr -d "${URL}" -l "6" -o "${TMP_PATH}/qrcode_boot.png" + [ -f "${TMP_PATH}/qrcode_boot.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode_boot.png" >/dev/null 2>/dev/null || true + + python ${WORK_PATH}/include/functions.py makeqr -f "${WORK_PATH}/include/qhxg.png" -l "7" -o "${TMP_PATH}/qrcode_qhxg.png" + [ -f "${TMP_PATH}/qrcode_qhxg.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode_qhxg.png" >/dev/null 2>/dev/null || true fi # Executes DSM kernel via KEXEC diff --git a/files/initrd/opt/rr/include/functions.py b/files/initrd/opt/rr/include/functions.py index aee0a631..06029c19 100644 --- a/files/initrd/opt/rr/include/functions.py +++ b/files/initrd/opt/rr/include/functions.py @@ -17,44 +17,74 @@ def cli(): """ pass +def mutually_exclusive_options(ctx, param, value): + other_option = 'file' if param.name == 'data' else 'data' + if value is not None and ctx.params.get(other_option) is not None: + raise click.UsageError(f'Illegal usage: `{param.name}` is mutually exclusive with `{other_option}`.') + return value + +def validate_required_param(ctx, param, value): + if not value and 'file' not in ctx.params and 'data' not in ctx.params: + raise click.MissingParameter(param_decls=[param.name]) + return value + @cli.command() -@click.option('-d', "--data", type=str, required=True, help="The data of QRCode.") -@click.option('-l', "--location", type=str, required=True, help="The location of QRCode. (tl, tr, bl, br, mid)") +@click.option('-d', "--data", type=str, callback=mutually_exclusive_options, is_eager=True, help="The data of QRCode.") +@click.option('-f', "--file", type=str, callback=mutually_exclusive_options, is_eager=True, help="The file of QRCode.") +@click.option('--validate', is_flag=True, callback=validate_required_param, expose_value=False, is_eager=True) +@click.option('-l', "--location", type=click.IntRange(0, 7), required=True, help="The location of QRCode. (range 0<=x<=7)") @click.option('-o', "--output", type=str, required=True, help="The output file of QRCode.") -def makeqr(data, location, output): +def makeqr(data, file, location, output): """ Generate a QRCode. """ + import fcntl, struct import qrcode from PIL import Image - qr = qrcode.QRCode(version=1, box_size=10, error_correction=qrcode.constants.ERROR_CORRECT_H, border=4) - qr.add_data(data) - qr.make(fit=True) - img = qr.make_image(fill_color="purple", back_color="white") - img = img.convert("RGBA") - pixels = img.load() - for i in range(img.size[0]): - for j in range(img.size[1]): - if pixels[i, j] == (255, 255, 255, 255): - pixels[i, j] = (255, 255, 255, 0) - - if os.path.exists(os.path.join(WORK_PATH, "logo.png")): - icon = Image.open(os.path.join(WORK_PATH, "logo.png")) - icon = icon.convert("RGBA") - img.paste(icon.resize((int(img.size[0] / 5), int(img.size[1] / 5))), (int((img.size[0] - int(img.size[0] / 5)) / 2), int((img.size[1] - int(img.size[1] / 5)) / 2))) - - alpha = Image.new("RGBA", (img.size[0] * 4, img.size[1] * 3), (0, 0, 0, 0)) - if location == "tl": - loc = (0, 0) - elif location == "tr": - loc = (alpha.size[0] - img.size[0], 0) - elif location == "bl": - loc = (0, alpha.size[1] - img.size[1]) - elif location == "br": - loc = (alpha.size[0] - img.size[0], alpha.size[1] - img.size[1]) - else: # elif location == "mid": - loc = (int((alpha.size[0] - img.size[0]) / 2), int((alpha.size[1] - img.size[1]) / 2)) + FBIOGET_VSCREENINFO = 0x4600 + FBIOPUT_VSCREENINFO = 0x4601 + FBIOGET_FSCREENINFO = 0x4602 + FBDEV = "/dev/fb0" + if data is not None: + qr = qrcode.QRCode(version=1, box_size=10, error_correction=qrcode.constants.ERROR_CORRECT_H, border=4) + qr.add_data(data) + qr.make(fit=True) + img = qr.make_image(fill_color="purple", back_color="white") + img = img.convert("RGBA") + pixels = img.load() + for i in range(img.size[0]): + for j in range(img.size[1]): + if pixels[i, j] == (255, 255, 255, 255): + pixels[i, j] = (255, 255, 255, 0) + + if os.path.exists(os.path.join(WORK_PATH, "logo.png")): + icon = Image.open(os.path.join(WORK_PATH, "logo.png")) + icon = icon.convert("RGBA") + img.paste(icon.resize((int(img.size[0] / 5), int(img.size[1] / 5))), (int((img.size[0] - int(img.size[0] / 5)) / 2), int((img.size[1] - int(img.size[1] / 5)) / 2))) + + if file is not None: + img = Image.open(file) + # img = img.convert("RGBA") + # pixels = img.load() + # for i in range(img.size[0]): + # for j in range(img.size[1]): + # if pixels[i, j] == (255, 255, 255, 255): + # pixels[i, j] = (255, 255, 255, 0) + + (xres, yres) = (1920, 1080) + with open(FBDEV, 'rb')as fb: + vi = fcntl.ioctl(fb, FBIOGET_VSCREENINFO, bytes(160)) + res = struct.unpack('I'*40, vi) + if res[0] != 0 and res[1] != 0: + (xres, yres) = (res[0], res[1]) + xqr, yqr = (int(xres / 8), int(xres / 8)) + img = img.resize((xqr, yqr)) + + alpha = Image.new("RGBA", (xres, yres), (0, 0, 0, 0)) + if int(location) not in range(0, 8): + location = 0 + loc = (img.size[0] * int(location), alpha.size[1] - img.size[1]) alpha.paste(img, loc) alpha.save(output) diff --git a/files/initrd/opt/rr/include/qhxg.png b/files/initrd/opt/rr/include/qhxg.png new file mode 100644 index 00000000..ebf8cbba Binary files /dev/null and b/files/initrd/opt/rr/include/qhxg.png differ diff --git a/files/initrd/opt/rr/init.sh b/files/initrd/opt/rr/init.sh index a90bbfe8..9cc87e7e 100755 --- a/files/initrd/opt/rr/init.sh +++ b/files/initrd/opt/rr/init.sh @@ -181,8 +181,11 @@ DSMLOGO="$(readConfigKey "dsmlogo" "${USER_CONFIG_FILE}")" if [ "${DSMLOGO}" = "true" -a -c "/dev/fb0" ]; then IP="$(getIP)" [ -n "${IP}" ] && URL="http://${IP}:7681" || URL="http://rr:7681/" - python ${WORK_PATH}/include/functions.py makeqr -d "${URL}" -l "bl" -o "${TMP_PATH}/qrcode.png" - [ -f "${TMP_PATH}/qrcode.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode.png" >/dev/null 2>/dev/null || true + python ${WORK_PATH}/include/functions.py makeqr -d "${URL}" -l "0" -o "${TMP_PATH}/qrcode_init.png" + [ -f "${TMP_PATH}/qrcode_init.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode_init.png" >/dev/null 2>/dev/null || true + + python ${WORK_PATH}/include/functions.py makeqr -f "${WORK_PATH}/include/qhxg.png" -l "7" -o "${TMP_PATH}/qrcode_qhxg.png" + [ -f "${TMP_PATH}/qrcode_qhxg.png" ] && echo | fbv -acufi "${TMP_PATH}/qrcode_qhxg.png" >/dev/null 2>/dev/null || true fi # Check memory