Customization: Logo
Relevant source files
The following files were used as context for generating this wiki page:The Logo Customization feature allows users to embed an image into the center of the generated QR code. This enhances branding and visual appeal. The system manages logo uploads, scaling, and automatically adjusts the QR code's Error Correction Capability (ECC) to maintain scannability when a logo is present.
This functionality is primarily managed within the main App component, with rendering handled by QrPreview and qrcode.react, and crucial logic supported by utility functions. The implementation carefully balances aesthetics with the technical requirements of QR codes, ensuring the final output remains functional.
Logo Upload and Management
The user can upload a logo via a file input or by dragging and dropping the file onto the preview area. The process includes validation for file size and type to ensure security and performance.
Sources: src/App.jsx:658-690, SECURITY_AUDIT_REPORT.md
Upload Flow
The upload process is handled by the onPickLogo function. It validates the file, creates a temporary blob URL for rendering, and updates the application's state.
This diagram shows the sequence of events when a user uploads a logo, including validation steps and state updates.
Sources: src/App.jsx:658-681, SECURITY_AUDIT_REPORT.md
State Management
Logo-related settings are managed by React state variables within the App component. These states are persisted in localStorage via the useLocalStorage custom hook.
| State Variable | Hook | Description | Initial Value |
|---|---|---|---|
logoUrl | React.useState | Stores the blob URL of the uploaded logo. | '' |
logoMode | useLocalStorage | The selected sizing mode for the logo ('auto', 's', 'm', 'l', 'custom'). | 'auto' |
customLogoScale | useLocalStorage | The user-defined scale for the logo when logoMode is 'custom'. | 0.2 |
Sources: src/App.jsx:400-402, src/App.jsx:405
Security Measures
File uploads are secured by client-side validation:
- File Size Limit: A hard limit of 4MB is enforced to prevent large file uploads.
- File Type Whitelist: Only
image/png,image/jpeg,image/jpg,image/webp, andimage/svg+xmlare accepted.
These measures mitigate risks associated with malicious or oversized file uploads.
Sources: src/App.jsx:662-674, SECURITY_AUDIT_REPORT.md
Logo Sizing and Scaling
The size of the logo relative to the QR code is crucial for scannability. The application provides several preset sizes and a custom slider for fine-tuning.
Sources: src/App.jsx:474-486, src/App.jsx:1109-1158
Sizing Modes
The logoMode state determines the scaling factor applied to the logo.
| Mode | Scale Value | Description |
|---|---|---|
auto | 0.2 (if logo) | Automatic default size. |
s | 0.15 | Small preset. |
m | 0.22 | Medium preset. |
l | 0.28 | Large preset. |
custom | customLogoScale | Uses the value from the custom scale slider. |
The final scale is determined by the scaleFromMode function.
// src/App.jsx:474-486
function scaleFromMode(mode) {
switch (mode) {
case 's':
return 0.15;
case 'm':
return 0.22;
case 'l':
return 0.28;
case 'custom':
return customLogoScale;
case 'auto':
default:
return logoUrl ? 0.2 : 0;
}
}
const scale = scaleFromMode(logoMode);
Sources: src/App.jsx:474-487
The final pixel dimensions of the logo (logoPx) are calculated by multiplying the QR code's total size by this scale factor. A "safety" indicator in the UI warns the user if the logo size becomes too large ('caution' > 25%, 'risky' > 30%).
Sources: src/App.jsx:488-489, src/App.jsx:1159-1174
Integration with QR Code Rendering
The logo is embedded into the QR code using the imageSettings prop of the qrcode.react library. This prop is configured within the qrProps object in App.jsx.
Sources: src/App.jsx:530-547
imageSettings Configuration
The imageSettings object is constructed based on the logo state.
| Property | Value | Description |
|---|---|---|
src | logoUrl | The URL of the logo image (the blob URL). |
height | Math.round(sizeNormalized * scale) | The calculated height of the logo in pixels. |
width | Math.round(sizeNormalized * scale) | The calculated width of the logo in pixels. |
excavate | true | This key property instructs qrcode.react to clear the area behind the logo. |
crossOrigin | 'anonymous' | Allows loading images from CORS-enabled URLs for canvas export. |
// src/App.jsx:533-541
const imageSettings = logoUrl
? {
src: logoUrl,
height: Math.round(sizeNormalized * scale),
width: Math.round(sizeNormalized * scale),
excavate: true,
crossOrigin: 'anonymous',
}
: undefined;
This configuration is then passed to <QRCodeCanvas> or <QRCodeSVG> via the spread qrProps.
Sources: src/App.jsx:533-541, src/components/QrPreview.jsx:47-56
Cross-Origin (CORS) Issues
When exporting a QR code with a logo to a raster format (PNG/JPG), the canvas can become "tainted" if the logo is loaded from a cross-origin URL that doesn't provide appropriate CORS headers. The ExportPanel component catches this specific error and displays a user-friendly message.
Sources: src/components/ExportPanel.jsx:70-75
Impact on Error Correction (ECC)
A logo obstructs a portion of the QR code's data modules. To compensate for this data loss and ensure the QR code remains scannable, a higher level of Error Correction Capability (ECC) is required. The application handles this automatically when eccMode is set to AUTO.
Sources: src/App.jsx:511-514, src/utils/qr-helpers.js:241-250
Automatic ECC Selection
The pickECC utility function determines the appropriate ECC level. If the user has not manually selected an ECC level, the function increases it based on the logo's scale.
This flowchart illustrates the logic of the pickECC function for automatically selecting the ECC level.
Sources: src/utils/qr-helpers.js:241-250, tests/qr-helpers.test.js:84-99
- No Logo or Small Logo (<10%): Defaults to
M(Medium, ~15% correction). - Medium Logo (≥10%): Upgrades to
Q(Quartile, ~25% correction). - Large Logo (≥22%) or Poor Contrast: Upgrades to
H(High, ~30% correction).
When the ECC level is automatically upgraded to 'H' due to a large logo, a temporary notice (showEccNotice) is displayed in the UI to inform the user.
Sources: src/App.jsx:522-528
Summary
The logo customization feature is a well-integrated system that provides significant branding value while actively managing the technical constraints of QR codes. It combines user-friendly UI controls for uploading and sizing with intelligent, automatic adjustments to the QR code's error correction level. Security is addressed through strict file validation, and potential cross-origin issues during export are handled gracefully. This ensures that even with a logo, the generated QR code remains robust and scannable.
Sources: README.md, src/App.jsx