From 4d6e69ea3856b5a9dfc459f8a63835e4eb62ae25 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Wed, 13 Sep 2023 22:04:46 -0500 Subject: [PATCH 1/2] [Enhancement] Render SeedQR small registration block in solid squares fixes #483 --- src/seedsigner/helpers/qr.py | 62 +++++++++++++++++++++++-- tests/screenshot_generator/generator.py | 12 +++-- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/seedsigner/helpers/qr.py b/src/seedsigner/helpers/qr.py index b986c6d7..5377a1a7 100644 --- a/src/seedsigner/helpers/qr.py +++ b/src/seedsigner/helpers/qr.py @@ -1,7 +1,7 @@ import qrcode from qrcode.image.styledpil import StyledPilImage from qrcode.image.styles.moduledrawers import CircleModuleDrawer, GappedSquareModuleDrawer -from PIL import Image +from PIL import Image, ImageDraw import subprocess class QR: @@ -13,19 +13,73 @@ class QR: return def qrimage(self, data, width=240, height=240, border=3, style=None, background_color="#444"): - qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=5, border=border ) + box_size = 5 + qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=box_size, border=border ) qr.add_data(data) qr.make(fit=True) if not style or style == QR.STYLE__DEFAULT: return qr.make_image(fill_color="black", back_color=background_color).resize((width,height)).convert('RGBA') else: if style == QR.STYLE__ROUNDED: - return qr.make_image( + qr_image = qr.make_image( fill_color="black", back_color=background_color, image_factory=StyledPilImage, module_drawer=CircleModuleDrawer() - ).resize((width,height)).convert('RGBA') + ) + + qr_image_width, _ = qr_image.size + qr_code_dims = int(qr_image_width / box_size) - 2*border + + if qr_code_dims > 21: + # The ROUNDED style mis-renders the small lower-right registration box in 25x25 + # and 29x29. + draw = ImageDraw.Draw(qr_image) + if qr_code_dims == 25: + # registration block starts at 16, 16 and is 5x5 + starting_point = 16 + border + + elif qr_code_dims == 29: + # The registration block starts at 20,20 and is 5x5 + starting_point = 20 + border + + else: + raise Exception(f"Unrecognized qrimage size: {qr_code_dims}") + + # Render black rectangular lines on top of the qr_image to square off + # the registration block. + lines = [ + ( + # top + (starting_point*box_size, starting_point*box_size), + (starting_point*box_size + 5*box_size - 1, starting_point*box_size + box_size - 1) + ), + ( + # right + (starting_point*box_size + 4*box_size, starting_point*box_size), + (starting_point*box_size + 5*box_size - 1, starting_point*box_size + 5*box_size - 1) + ), + ( + # left + (starting_point*box_size, starting_point*box_size), + (starting_point*box_size + box_size - 1, starting_point*box_size + 5*box_size - 1) + ), + ( + # bottom + (starting_point*box_size + box_size, starting_point*box_size + 4*box_size), + (starting_point*box_size + 5*box_size - 1, starting_point*box_size + 5*box_size - 1) + ), + ( + # center dot + (starting_point*box_size + 2*box_size, starting_point*box_size + 2*box_size), + (starting_point*box_size + 3*box_size - 1, starting_point*box_size + 3*box_size - 1) + ) + ] + + for line in lines: + draw.rectangle(line, fill="black") + + return qr_image.resize((width,height)).convert('RGBA') elif style == QR.STYLE__GRID: return qr.make_image( diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py index 83a58135..f3300ae1 100644 --- a/tests/screenshot_generator/generator.py +++ b/tests/screenshot_generator/generator.py @@ -65,10 +65,12 @@ def test_generate_screenshots(target_locale): mnemonic_12b = ["abandon"] * 11 + ["about"] seed_12 = Seed(mnemonic=mnemonic_12, passphrase="cap*BRACKET3stove", wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) seed_12b = Seed(mnemonic=mnemonic_12b, wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) - seed_24 = Seed(mnemonic=mnemonic_24, passphrase="some-PASS*phrase9", wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) + seed_24 = Seed(mnemonic=mnemonic_24, wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) + seed_24_w_passphrase = Seed(mnemonic=mnemonic_24, passphrase="some-PASS*phrase9", wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH) controller.storage.seeds.append(seed_12) controller.storage.seeds.append(seed_12b) - controller.storage.set_pending_seed(seed_24) + controller.storage.seeds.append(seed_24) + controller.storage.set_pending_seed(seed_24_w_passphrase) UnhandledExceptionViewFood = ["IndexError", "line 1, in some_buggy_code.py", "list index out of range"] # Pending mnemonic for ToolsCalcFinalWordShowFinalWordView @@ -155,11 +157,13 @@ def test_generate_screenshots(target_locale): (seed_views.SeedWordsBackupTestSuccessView, dict(seed_num=0)), (seed_views.SeedTranscribeSeedQRFormatView, dict(seed_num=0)), (seed_views.SeedTranscribeSeedQRWarningView, dict(seed_num=0)), - (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, num_modules=25), "SeedTranscribeSeedQRWholeQRView_12_Standard"), (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=21), "SeedTranscribeSeedQRWholeQRView_12_Compact"), + (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, num_modules=25), "SeedTranscribeSeedQRWholeQRView_12_Standard"), + (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=25), "SeedTranscribeSeedQRWholeQRView_24_Compact"), + (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__SEEDQR, num_modules=29), "SeedTranscribeSeedQRWholeQRView_24_Standard"), # Screenshot doesn't render properly due to how the transparency mask is pre-rendered - # (seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR)), + (seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR)), (seed_views.SeedTranscribeSeedQRConfirmQRPromptView, dict(seed_num=0)), From 6232e300816ae55d9f96a0d58d4ceddc9926b2b5 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Wed, 13 Sep 2023 22:08:12 -0500 Subject: [PATCH 2/2] revert zoomed in transcription UI to be commented out --- tests/screenshot_generator/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py index f3300ae1..88f57fa4 100644 --- a/tests/screenshot_generator/generator.py +++ b/tests/screenshot_generator/generator.py @@ -163,7 +163,7 @@ def test_generate_screenshots(target_locale): (seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__SEEDQR, num_modules=29), "SeedTranscribeSeedQRWholeQRView_24_Standard"), # Screenshot doesn't render properly due to how the transparency mask is pre-rendered - (seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR)), + # (seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR)), (seed_views.SeedTranscribeSeedQRConfirmQRPromptView, dict(seed_num=0)),