Skip to content

Conversation

Copy link

Copilot AI commented Nov 1, 2025

  • Explore repository structure and understand QR code generation
  • Add UI controls to select/upload a logo image
  • Update BarcodeHelpers to support logo overlay on QR codes
  • Update BarcodeImageItem model to store logo image data
  • Modify GetQrCodeBitmapFromText to overlay logo on center
  • Add logo support for SVG export
  • Update MainPage.xaml with logo picker UI
  • Update MainViewModel to handle logo selection
  • Add proper disposal of logo images to prevent memory leaks
  • Address code review feedback
  • Preserve logo aspect ratio to prevent distortion
  • Add logo size slider with error correction-based limits
  • Optimize SVG encoding by resizing images before base64 conversion
  • Add history support for logo images with local storage persistence
  • Add logo padding pixels to history persistence
  • Move history storage from settings to dedicated file
  • Pass HistoryItem between pages for full state restoration
  • Security scan

Summary of changes:

  • Added logo overlay functionality to QR code generation with center positioning
  • Logo dimensions now preserve aspect ratio - no stretching or distortion
  • Logo is displayed with white background rectangle that matches logo dimensions
  • Adjustable logo size with slider control (5% to maximum based on error correction)
  • Maximum logo size dynamically calculated based on QR code error correction level:
    • Low (L): max 5.6% of QR code area (7% capacity × 80% safety factor)
    • Medium (M): max 12% of QR code area (15% × 80%)
    • Quartile (Q): max 20% of QR code area (25% × 80%)
    • High (H): max 24% of QR code area (30% × 80%)
  • Full support for both PNG (bitmap) and SVG (embedded base64) export formats
  • Three UI controls: "Add Logo" button, "Remove Logo" button, and size slider
  • SVG files optimized - logo images resized before base64 encoding to reduce file size
  • History saves and restores all logo settings:
    • Logo images persisted to local app storage (LocalFolder/LogoImages)
    • Logo file path, size percentage, and padding pixels stored in history items
    • Automatic logo restoration when selecting from history
    • Logo cleared when selecting history item without logo
    • History stored in dedicated JSON file (LocalFolder/History.json) instead of settings
  • Cross-page state preservation:
    • Full state (colors, logos, settings) preserved when navigating between pages
    • HistoryItem passed as navigation parameter between Main, Settings, and Decoding pages
    • Backward compatible with string parameters
  • Leverages QR code error correction to ensure codes remain scannable with logo overlay
  • Proper resource management with Bitmap disposal in ViewModel destructor
  • Uses stream-based file access for compatibility with cloud storage and restricted locations

Aspect Ratio Preservation:

  • Calculates aspect ratio of source image
  • For wide images (width > height): sets width to max size, calculates proportional height
  • For tall images (height > width): sets height to max size, calculates proportional width
  • Square images: both dimensions set to max size
  • Background rectangle automatically sized to fit actual logo dimensions with padding

Logo Size Control:

  • Size slider appears below logo buttons when logo is selected
  • Minimum size: 5% of QR code dimensions
  • Maximum size: Dynamically calculated based on error correction capacity
  • Real-time percentage display
  • Slider automatically adjusts maximum when error correction level changes
  • Default size: 20% (if error correction level allows)

SVG Optimization:

  • Images resized to final display dimensions before base64 encoding
  • Uses high-quality bicubic interpolation for smooth scaling
  • Significantly reduces SVG file size for large source images

History Persistence:

  • Logo images saved as PNG files in app's local storage folder
  • Unique filename with timestamp and GUID to prevent conflicts
  • LogoImagePath, LogoSizePercentage, and LogoPaddingPixels stored in HistoryItem model
  • Logo automatically loaded when history item selected
  • Logo size and padding/zoom settings fully restored from history
  • SaveCurrentStateToHistory() made async to properly save logo files
  • Error handling for logo save/load operations with debug logging
  • History stored in separate History.json file instead of settings to avoid size limitations
  • Automatic migration from old settings-based storage to new file-based storage
  • One-time migration preserves existing history and clears old settings entry

File-Based History Storage:

  • History saved to LocalFolder/History.json instead of application settings
  • Avoids JSON size limitations that occurred with logo image paths in settings
  • Uses System.Text.Json.JsonSerializer with indented formatting for readability
  • Migration logic: On first load after update, automatically migrates existing history from settings to file
  • If legacy history found in settings: migrates to file, saves, and clears old settings entry
  • If no legacy history: directly uses new file storage
  • Backward compatible - existing users' history is preserved seamlessly

Cross-Page Navigation State Preservation:

  • MainViewModel creates HistoryItem from current state when navigating to other pages

  • SettingsViewModel stores and returns HistoryItem when returning to main page

  • DecodingViewModel stores and returns HistoryItem when returning to main page

  • OnNavigatedTo methods accept both HistoryItem (full state) and string (backward compatible)

  • RestoreFromHistoryItem method in MainViewModel applies complete state restoration

  • State preserved includes: text content, foreground/background colors, error correction level, logo image, logo size percentage, logo padding pixels

  • currentLogoPath field tracks logo file path for seamless navigation

  • Works across all navigation flows: Main ↔ Settings, Main ↔ Decoding, Decoding → Edit QR Code

  • Fixes Punchout to add a logo or image to center of QR Code #14

Original prompt

This section details on the original issue you should resolve

<issue_title>Punchout to add a logo or image to center of QR Code</issue_title>
<issue_description></issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add logo or image to center of QR code Add logo overlay to QR code center Nov 1, 2025
Copilot AI requested a review from TheJoeFin November 1, 2025 04:10
Copilot finished work on behalf of TheJoeFin November 1, 2025 04:10
@TheJoeFin
Copy link
Owner

@copilot looks good, I make sure the logo image chosen for the center of the code does not get stretched and distorted, consider the aspect ratio of the picked image before making the punchout

Copy link
Author

Copilot AI commented Nov 1, 2025

@copilot looks good, I make sure the logo image chosen for the center of the code does not get stretched and distorted, consider the aspect ratio of the picked image before making the punchout

Updated both PNG and SVG implementations to preserve logo aspect ratio. The logo now scales to fit within the 20% maximum size constraint while maintaining its original proportions:

  • Wide logos: max width, proportional height
  • Tall logos: max height, proportional width
  • Square logos: equal dimensions

The background rectangle also adjusts to match the actual logo dimensions. Fixed in commit 305bd87.

Copilot finished work on behalf of TheJoeFin November 1, 2025 16:04
@TheJoeFin
Copy link
Owner

@copilot looking good. Two things to change

  1. Add a size slider to adjust the size of the logo punchout. but also calculate how many lost QR code blocks and the error correction level to set the maximum size of the logo possible
  2. When saving out an SVG, resize the image first before encoding it to make the SVG file not too big

Copy link
Author

Copilot AI commented Nov 1, 2025

@copilot looking good. Two things to change

  1. Add a size slider to adjust the size of the logo punchout. but also calculate how many lost QR code blocks and the error correction level to set the max...

Implemented both requested features in commit 763412d:

1. Logo size slider with error correction-based limits:

  • Added slider UI (5% to max, default 20%)
  • Maximum size calculated dynamically based on error correction level:
    • L (Low): max 5.6% (7% capacity × 80% safety factor)
    • M (Medium): max 12% (15% × 80%)
    • Q (Quartile): max 20% (25% × 80%)
    • H (High): max 24% (30% × 80%)
  • Slider auto-adjusts when error correction changes
  • Shows current percentage in real-time

2. SVG optimization:

  • Images now resized to final display dimensions before base64 encoding
  • Uses high-quality bicubic interpolation for smooth scaling
  • Significantly reduces SVG file size for large source images

The slider appears below the logo buttons and only shows when a logo is selected.

Copilot AI changed the title Add logo overlay to QR code center Add logo overlay to QR code center with adjustable size Nov 1, 2025
Copilot finished work on behalf of TheJoeFin November 1, 2025 16:21
Enhanced logo overlay precision by aligning dimensions and padding to QR code module boundaries. Updated SVG logo embedding for consistency and accuracy. Increased allowable logo size for error correction levels. Added null checks for clipboard operations to improve robustness. Refactored code for better readability and maintainability.
Introduced `logoPaddingPixels` parameter to control padding or cropping around logos in QR codes. Updated `BarcodeHelpers`, `BarcodeImageItem`, and `MainViewModel` to support this feature. Enhanced SVG and bitmap generation logic, added a UI slider for dynamic padding adjustment, and improved code consistency and rendering quality.
Refactored QR code logo embedding logic to use "punchout size" for better clarity and flexibility. Simplified calculations for punchout area, logo dimensions, and padding. Updated SVG embedding to reduce file size and align with new logic. Revised `MainPage.xaml` labels and tooltips to reflect updated terminology and functionality.
Updated `OverlayLogoOnQrCode` and `EmbedLogoInSvg` methods to accept a `backgroundColor` parameter, enabling customization of the punchout background color in both bitmap and SVG formats. Adjusted related logic and comments to reflect this enhancement.
- Adjusted QR code margin for tighter generation.
- Enhanced logo overlay logic with improved scaling and alignment.
- Refined padding and logo size calculations for better accuracy.
- Updated default logo settings for size and padding.
- Simplified error correction level handling with fixed values.
- Improved stream handling with explicit type usage.
- Enhanced UI with `SplitButton` for logo options and sliders.
- Consolidated bindings and improved code readability in XAML.
- Standardized formatting and improved code consistency.
- Fixed logo resizing issues and minor binding inconsistencies.
@TheJoeFin
Copy link
Owner

@copilot make sure that history saves and restores the data around images as well such as size, scale, and store the logo in local app storage and a path to that item on the history item.

Copy link
Author

Copilot AI commented Nov 18, 2025

@copilot make sure that history saves and restores the data around images as well such as size, scale, and store the logo in local app storage and a path to that item on the history item.

Implemented history support for logo images in commit 9a2e144:

Logo Storage:

  • Logo images saved to LocalFolder/LogoImages as PNG files
  • Unique filenames with timestamp and GUID to prevent conflicts
  • File path stored in HistoryItem

HistoryItem Properties Added:

  • LogoImagePath: Path to saved logo file
  • LogoSizePercentage: Logo size setting

Restoration:

  • When selecting history item, logo automatically loaded from stored path
  • Logo size percentage restored
  • If history item has no logo, current logo is cleared
  • Error handling with debug logging for load failures

Implementation:

  • Made SaveCurrentStateToHistory() async to properly save logo files
  • Updated all callers to await the async method
  • Logo loaded via LoadLogoFromHistory() when history item selected

Copilot AI changed the title Add logo overlay to QR code center with adjustable size Add logo overlay to QR code center with adjustable size and history persistence Nov 18, 2025
Copilot finished work on behalf of TheJoeFin November 18, 2025 20:00
@TheJoeFin
Copy link
Owner

@copilot also store and retrieve the logo image zoom/padding pixels number with the history item

Copy link
Author

Copilot AI commented Nov 18, 2025

@copilot also store and retrieve the logo image zoom/padding pixels number with the history item

Added logo padding pixels to history persistence in commit 9c23fe9:

HistoryItem Property Added:

  • LogoPaddingPixels: Stores logo zoom/padding setting (default 4.0)

Implementation:

  • Logo padding pixels saved with each history item in SaveCurrentStateToHistory()
  • Logo padding pixels restored when selecting history item in OnSelectedHistoryItemChanged()
  • Works alongside existing logo path and size percentage storage

The padding/zoom setting is now fully preserved across app sessions and history navigation.

Copilot finished work on behalf of TheJoeFin November 18, 2025 20:07
@TheJoeFin
Copy link
Owner

@copilot now there is an error where with the new image field the settings cannot hold the history JSON in one setting, so break out the settings JSON to save it in the local storage. Also ensure there is a migration check if there is history it needs to be saved to a file and cleared out, if not then just use the standard storage

Copy link
Author

Copilot AI commented Nov 19, 2025

@copilot now there is an error where with the new image field the settings cannot hold the history JSON in one setting, so break out the settings JSON to save it in the local storage. Also ensure ther...

Moved history storage from settings to separate file in commit 93694fe:

New Storage Location:

  • History saved to LocalFolder/History.json file
  • Avoids settings size limitations caused by logo image paths
  • Uses JSON serialization with proper formatting

Migration Logic:

  • On first load, checks for existing history in settings
  • If found: automatically migrates to file storage and clears settings
  • If not found: uses file storage directly
  • Migration is one-time and automatic

Implementation:

  • SaveHistoryToFile(): Saves HistoryItems collection to History.json
  • LoadHistory(): Loads from file first, falls back to migration if needed
  • Error handling with debug logging for both operations

The change resolves the JSON size limit issue while preserving all existing history data through automatic migration.

Copilot AI changed the title Add logo overlay to QR code center with adjustable size and history persistence Add logo overlay to QR code center with adjustable size and file-based history persistence Nov 19, 2025
Copilot finished work on behalf of TheJoeFin November 19, 2025 00:59
@TheJoeFin
Copy link
Owner

@copilot when moving between pages use a HistoryItem in the parameters that way the full state can be restored such as colors and logos if there are any

Copy link
Author

Copilot AI commented Nov 19, 2025

@copilot when moving between pages use a HistoryItem in the parameters that way the full state can be restored such as colors and logos if there are any

Updated navigation to pass HistoryItem for full state restoration in commit 8d460d6:

MainViewModel Changes:

  • OnNavigatedTo now accepts both HistoryItem and string parameters (backward compatible)
  • RestoreFromHistoryItem method restores all state: text, colors, error correction, logo, size, and padding
  • CreateCurrentStateHistoryItem creates HistoryItem from current state for navigation
  • Tracks currentLogoPath to preserve logo across page transitions
  • Navigation to Settings and Decoding passes HistoryItem

SettingsViewModel Changes:

  • Stores received HistoryItem in navigationHistoryItem field
  • Returns HistoryItem when navigating back to MainViewModel
  • Backward compatible with string parameters

DecodingViewModel Changes:

  • Stores received HistoryItem in navigationHistoryItem field
  • GoBack returns HistoryItem to preserve full state
  • EditQrCode creates new HistoryItem with decoded text while preserving colors/logo
  • Backward compatible with string parameters

State Preserved:

  • Text content, foreground/background colors, error correction level
  • Logo image (if present), logo size percentage, logo padding pixels
  • Full round-trip state preservation through navigation flows

Copilot AI changed the title Add logo overlay to QR code center with adjustable size and file-based history persistence Add logo overlay to QR code center with adjustable size, file-based history persistence, and cross-page state preservation Nov 19, 2025
Copilot finished work on behalf of TheJoeFin November 19, 2025 22:18
Refine the logic for setting the SizeTextVisible property to
also hide the size text when a logo image is present, in
addition to the existing HideMinimumSizeText condition.
Reduced the `Spacing` property of the `StackPanel` named `QrCodeOptions` from `12` to `6` to optimize spacing.
Decreased the `Width` of the "Code Color" and "Background Color" buttons from `68` to `48` to improve the visual design and save space in the user interface.
@TheJoeFin TheJoeFin marked this pull request as ready for review November 20, 2025 03:14
@TheJoeFin TheJoeFin merged commit 1371b2f into dev Nov 20, 2025
@TheJoeFin TheJoeFin deleted the copilot/add-logo-to-qr-code-again branch November 20, 2025 03:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants