Practical development of QR code generation tool for moving cars

Practical development of QR code generation tool for moving cars

This article describes how to develop a mobile QR code generation tool, including desktop versions implemented by C#and Avalonia, and online versions implemented by Blazor front-end and. NET Web API, covering requirements analysis, core code implementation, UI design and MVVM pattern applications.

最后更新 3/10/2025 7:54 PM
沙漠尽头的狼
预计阅读 20 分钟
分类
.NET
标签
.NET C# Blazor Avalonia UI MVVM

1. Demand analysis and plan design

background issues

In a modern city with heavy traffic, parking problems follow suit, and moving cars has become one of the daily problems faced by car owners. In the past, in order to facilitate others to contact and move cars, people often placed a note with a telephone number written on it in a conspicuous position in the car, or placed a car-moving decoration engraved with a mobile phone number. This traditional method may seem simple and direct, but it hides many hidden dangers.

The first is the issue of privacy disclosure. Nowadays, the security of personal information is crucial. Exposing phone numbers at will in public places is like opening your own privacy door. Lawless elements will use this information to maliciously harass, and sales calls and fraudulent text messages will follow one after another, making people unbearable. There have been news reports that some "number copying people" shuttled through parking lots to collect mobile phone numbers, and then sold this information to marketing companies or fraud gangs in batches, causing the lives of car owners to be flooded with various spam information.

In addition to privacy leaks, it is also common for mobile numbers to be abused. Sometimes it is only a temporary parking for a short while, but you often receive calls to move a car. Some people even make random calls in non-emergency situations, delaying the owner's time. What is more serious is that people with ill intentions may use mobile phones to commit fraud, inducing car owners to click on links or transfer money under false reasons such as vehicle violations and accidents, causing property losses to the car owners.

solutions

In order to solve the above problems, we have developed a simple and practical two-dimensional code generation tool for moving cars, which achieves the following functions:

  1. Quickly generate QR code containing car owner contact information
  2. You can call the owner with one click by scanning the code
  3. Support customized car moving prompt text
  4. The mobile phone number is encrypted to protect the privacy of the owner
  5. Available in two ways: offline desktop version and online web version

Unlike the traditional direct display of phone numbers, our car moving QR code tool uses encryption technology to ensure that the owner's mobile phone number will not be directly exposed. At the same time, scanning the code to jump to the special car-moving page not only improves the user experience, but also reduces the risk of the number being abused. This article will detail these two implementations: a desktop application version based on C#and Avalonia, and an online web version based on the Blazor front-end and the. NET Web API.

The effect is as follows. A detailed page will pop up after WeChat scanning code:

On the detailed page, you can click ** to call the car owner ** or click the green hyperlink ** to generate a car moving code **:

2. Core QR code generation code

首先,让我们看一下核心的二维码生成逻辑。这部分代码封装在CodeWF.Tools项目的QrCodeGenerator类中:

using ImageMagick;
using ImageMagick.Drawing;
using ZXing;
using ZXing.QrCode;

namespace CodeWF.Tools.Image;

public static class QrCodeGenerator
{
    public static void GenerateQrCode(string title, string content, string imagePath, string? subTitle = "")
    {
        var qrCodeWriter = new BarcodeWriterPixelData
        {
            Format = BarcodeFormat.QR_CODE,
            Options = new QrCodeEncodingOptions
            {
                Width = 400,
                Height = 400,
                Margin = 1,
                ErrorCorrection = ZXing.QrCode.Internal.ErrorCorrectionLevel.H,
                CharacterSet = "UTF-8",
                DisableECI = true
            }
        };

        var pixelData = qrCodeWriter.Write(content);

        using var qrCodeImage = new MagickImage();
        var settings = new PixelReadSettings((uint)pixelData.Width, (uint)pixelData.Height, StorageType.Char, PixelMapping.RGBA);
        qrCodeImage.ReadPixels(pixelData.Pixels, settings);

        var backgroundHeight = string.IsNullOrWhiteSpace(subTitle) ? 600u : 630u;
        using var background = new MagickImage(MagickColors.White, 500, backgroundHeight);

        background.BorderColor = new MagickColor("#2888E2");
        background.Border(8);

        var titleText = new Drawables()
            .Font("SimHei")
            .FontPointSize(95)
            .FillColor(new MagickColor("#FF5722"))
            .TextAlignment(TextAlignment.Center)
            .Text(250, 120, title);
        background.Draw(titleText);

        background.Composite(qrCodeImage, 50, 170, CompositeOperator.Over);

        if (!string.IsNullOrWhiteSpace(subTitle))
        {
            var subTitleText = new Drawables()
                .Font("SimHei")
                .FontPointSize(20)
                .FillColor(new MagickColor("#333333"))
                .TextAlignment(TextAlignment.Center)
                .Text(250, 600, subTitle);
            background.Draw(subTitleText);
        }

        //using var logo = new MagickImage("logo.png");
        //logo.Resize(100, 100);
        //background.Composite(logo, 250, 250, CompositeOperator.Over);

        background.Quality = 100;
        background.Write(imagePath);
    }
}

The above code uses the NuGet package: ZXing.Net.Bindings.Magick. ZXing.NET is used to generate QR code matrix data, while Magick.NET is used for image processing and synthesis, achieving the following functions:

  1. Create a high-quality QR code and set a higher error correction level (H level), so that the QR code can be recognized normally even if it is partially blocked
  2. Generate a background image with white background and blue edges
  3. Add custom title text at the top
  4. Synthesize QR code images onto the background
  5. Add custom subtitle text at the bottom of the QR code
  6. Save as high-quality PNG images

This design makes the final generated QR code for moving the car both beautiful and practical.

挪车二维码

3. Implementation of offline desktop version

1. user interface design

使用Avalonia框架设计用户界面,界面定义在NuoCheView.axaml文件中:

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:vm="clr-namespace:CodeWF.Modules.Converter.ViewModels"
             xmlns:prism="http://prismlibrary.com/"
             xmlns:u="https://irihi.tech/ursa"
             xmlns:i18n="https://codewf.com"
             xmlns:language="clr-namespace:Localization"
             prism:ViewModelLocator.AutoWireViewModel="True"
             x:CompileBindings="True"
             x:DataType="vm:NuoCheViewModel"
             d:DesignHeight="450"
             d:DesignWidth="800"
             x:Class="CodeWF.Modules.Converter.Views.NuoCheView"
             mc:Ignorable="d">
    <StackPanel Margin="10" HorizontalAlignment="Center">
        <u:Form LabelPosition="Left" LabelWidth="*">
            <TextBox Width="300" u:FormItem.Label="{i18n:I18n {x:Static language:NuoCheView.InputPhoneNumber}}"
                     u:FormItem.IsRequired="True" Text="{Binding PhoneNumber}" />
            <TextBox Width="300" u:FormItem.Label="{i18n:I18n {x:Static language:NuoCheView.InputTitle}}"
                     u:FormItem.IsRequired="True" Text="{Binding InputTitle}" />
            <StackPanel Orientation="Horizontal" u:FormItem.Label="{i18n:I18n {x:Static language:NuoCheView.EnableSubTitle}}">
                <CheckBox IsChecked="{Binding EnableSubTitle}" Command="{Binding EnableSubTitleHandler}" VerticalAlignment="Center" Content="显示" Margin="5 0" />
                <TextBox Width="300" Text="{Binding SubTitle}" IsEnabled="{Binding EnableSubTitle}" VerticalAlignment="Center" />
            </StackPanel>
        </u:Form>

        <StackPanel Orientation="Horizontal" Spacing="10" Margin="0,0,0,10">
            <Button Content="{i18n:I18n {x:Static language:NuoCheView.CreateButtonContent}}"
                    Command="{Binding GenerateQrCode}" />
            <Button Content="{i18n:I18n {x:Static language:NuoCheView.SaveQrCodeFileTitle}}"
                    Command="{Binding SaveQrCode}" />
            <HyperlinkButton Content="{i18n:I18n {x:Static language:NuoCheView.PreviewNuoCheUrl}}"
                             NavigateUri="{Binding GeneratedUrl}" Classes="WithIcon Underline"
                             VerticalAlignment="Center" />
        </StackPanel>

        <Image Source="{Binding QrCodeImage}" Width="340" Height="340" DragDrop.AllowDrop="True">
            <Interaction.Behaviors>
                <EventTriggerBehavior EventName="PointerPressed">
                    <InvokeCommandAction Command="{Binding RaisePointerPressed}" PassEventArgsToCommand="True" />
                </EventTriggerBehavior>
            </Interaction.Behaviors>
        </Image>
    </StackPanel>
</UserControl>

The interface layout is concise and clear, mainly including:

  1. Three input boxes: mobile phone number and QR code title, optional QR code subtitle
  2. Three operation buttons: generate QR code, save QR code, and preview the car moving page
  3. An image display area: displays the generated QR code and supports drag and drop operations

The achieved results are as follows:

离线版界面截图

2. View model implementation

NuoCheViewModel.cs中实现业务逻辑:

using Avalonia.Input;
using Avalonia.Media.Imaging;
using Avalonia.Platform.Storage;
using AvaloniaXmlTranslator;
using CodeWF.Core.IServices;
using CodeWF.LogViewer.Avalonia;
using CodeWF.Tools.Image;
using HashidsNet;
using ReactiveUI;

namespace CodeWF.Modules.Converter.ViewModels;

public class NuoCheViewModel : ReactiveObject
{
    private readonly INotificationService _notificationService;
    private readonly IFileChooserService _fileChooserService;
    private string _inputTitle;
    private long _phoneNumber;
    private Bitmap? _qrCodeImage;
    private string _qrCodeImagePath;
    private string _generatedUrl;
    private string _subTitle;
    private bool _enableSubTitle;

    public NuoCheViewModel(INotificationService notificationService, IFileChooserService fileChooserService)
    {
        _notificationService = notificationService;
        _fileChooserService = fileChooserService;

        InputTitle = I18nManager.Instance.GetResource(Localization.NuoCheView.DefaultInputTitle);
        PhoneNumber = 16899999999;
        SubTitle = $"{I18nManager.Instance.GetResource(Localization.NuoCheView.DefaultSubTitlePrefix)}: {PhoneNumber}";
        EnableSubTitle = false;
    }

    public string InputTitle
    {
        get => _inputTitle;
        set => this.RaiseAndSetIfChanged(ref _inputTitle, value);
    }

    public long PhoneNumber
    {
        get => _phoneNumber;
        set => this.RaiseAndSetIfChanged(ref _phoneNumber, value);
    }

    public Bitmap? QrCodeImage
    {
        get => _qrCodeImage;
        private set => this.RaiseAndSetIfChanged(ref _qrCodeImage, value);
    }

    public string QrCodeImagePath
    {
        get => _qrCodeImagePath;
        private set => this.RaiseAndSetIfChanged(ref _qrCodeImagePath, value);
    }

    public string GeneratedUrl
    {
        get => _generatedUrl;
        private set => this.RaiseAndSetIfChanged(ref _generatedUrl, value);
    }

    public string SubTitle
    {
        get => _subTitle;
        set => this.RaiseAndSetIfChanged(ref _subTitle, value);
    }

    public bool EnableSubTitle
    {
        get => _enableSubTitle;
        set => this.RaiseAndSetIfChanged(ref _enableSubTitle, value);
    }

    public void EnableSubTitleHandler()
    {
        SubTitle = $"{I18nManager.Instance.GetResource(Localization.NuoCheView.DefaultSubTitlePrefix)}: {PhoneNumber}";
    }

    public void GenerateQrCode()
    {
        if (string.IsNullOrWhiteSpace(InputTitle))
        {
            _notificationService.Show(I18nManager.Instance.GetResource(Localization.NuoCheView.Title),
                I18nManager.Instance.GetResource(Localization.NuoCheView.NeedInputTip));
            return;
        }

        try
        {
            var encodedPhone = new Hashids("codewf").EncodeLong(PhoneNumber);

            GeneratedUrl =
                $"https://codewf.com/nuoche?p={encodedPhone}";
            QrCodeImagePath = Path.Combine(Path.GetTempPath(), "nuoche.png");

            QrCodeGenerator.GenerateQrCode(InputTitle, GeneratedUrl, QrCodeImagePath, 
                EnableSubTitle ? SubTitle : null);

            QrCodeImage = new Bitmap(QrCodeImagePath);
        }
        catch (Exception ex)
        {
            Logger.Error(I18nManager.Instance.GetResource(Localization.NuoCheView.CreateErrorMessage), ex);
            _notificationService.Show(I18nManager.Instance.GetResource(Localization.NuoCheView.Title),
                $"{I18nManager.Instance.GetResource(Localization.NuoCheView.CreateErrorMessage)}: {ex}");
        }
    }


    public async Task SaveQrCode()
    {
        if (QrCodeImage == null || string.IsNullOrEmpty(QrCodeImagePath))
        {
            _notificationService.Show(I18nManager.Instance.GetResource(Localization.NuoCheView.SaveNotificationTitle),
                I18nManager.Instance.GetResource(Localization.NuoCheView.SaveNoQrCodeMessage));
            return;
        }

        try
        {
            var file = await _fileChooserService.SaveFileAsync(
                I18nManager.Instance.GetResource(Localization.NuoCheView.SaveQrCodeFileTitle),
                new[]
                {
                    new FilePickerFileType(
                        I18nManager.Instance.GetResource(Localization.NuoCheView.SaveQrCodeFileFormat))
                    {
                        Patterns = new[] { "*.png" }
                    }
                }
            );

            if (file != null)
            {
                File.Copy(QrCodeImagePath, file, true);
                _notificationService.Show(
                    I18nManager.Instance.GetResource(Localization.NuoCheView.SaveQrCodeSuccessTitle),
                    I18nManager.Instance.GetResource(Localization.NuoCheView.SaveQrCodeSuccessMessage));
            }
        }
        catch (Exception ex)
        {
            _notificationService.Show(I18nManager.Instance.GetResource(Localization.NuoCheView.SaveNotificationTitle),
                $"{I18nManager.Instance.GetResource(Localization.NuoCheView.SaveQrCodeErrorMessage)}: {ex.Message}");
        }
    }

    public async Task RaisePointerPressed(PointerPressedEventArgs e)
    {
        if (string.IsNullOrWhiteSpace(QrCodeImagePath) || !File.Exists(QrCodeImagePath))
        {
            return;
        }

        var dragData = new DataObject();
        if (await _fileChooserService.StorageProvider.TryGetFileFromPathAsync(QrCodeImagePath) is { } storageFile)
        {
            dragData.Set(DataFormats.Files, new[] { storageFile });
        }

        await DragDrop.DoDragDrop(e, dragData, DragDropEffects.Copy);
    }
}

The view model implements the following functions:

      • Data binding **: Manage user input and UI status
      • QR code generation **: Call core generation logic and display results
      • File saving **: Save the generated QR code to the location specified by the user
      • Drag and drop support **: Allow users to directly drag and drop QR code images to other applications
      • Error handling **: Provide friendly error tips

值得一提的是,我们使用了Hashids库对手机号进行编码,提高了隐私保护。这样,即使二维码被公开展示,他人也无法直接获取车主的真实手机号(当然最后一步进入拨号界面时会显示真实手机号,这里可考虑使用虚拟号码屏蔽真实手机号)。

Drag and drop to save the QR code effect:

拖拽保存挪车二维码

4. Implementation of online web version

In addition to the desktop application version, we have also developed a Blazor-based online mobile QR code generation tool, which is convenient for users to use without installing software.

Online access address: https://www.example.com

Create a moving code on the PC side:

在线PC端创建挪车码

Create a moving code on the mobile phone:

在线手机端创建挪车码

1. Features of online generation of moving codes

Compared with the desktop version, the online version has the following characteristics:

      • No installation required **: Access and use directly through browser
      • Two-way function **: You can generate a QR code or directly access the parsed car moving page
      • Mobile friendly **: Optimize the display and interactive experience on mobile devices
      • Elegant UI design **: Use modern UI components and interactions

2. implementations

The online version is implemented using ** Blazor **, and the core code structure is as follows:

@page "/NuoChe"
@using HashidsNet
@inject IOptions<SiteOption> SiteOption
@layout EmptyLayout

@code {
    [SupplyParameterFromQuery]
    public string? P { get; set; }

    public const string Slug = "nuoche";

    private long? _decodePhone;

    protected override void OnInitialized()
    {
        base.OnInitialized();
        if (!string.IsNullOrWhiteSpace(P))
        {
            _decodePhone = new Hashids("codewf").DecodeLong(P)[0];
        }
    }
}

<PageTitle>免费挪车码</PageTitle>

<div class="nuoche-container">
    @if (string.IsNullOrWhiteSpace(P))
    {
        <div class="generator-container">
            <h1 class="generator-title">挪车码在线生成器</h1>
            <div class="input-group">
                <label for="phoneNumber">手机号码</label>
                <input type="tel" id="phoneNumber" placeholder="请输入手机号码" />
            </div>
            <div class="input-group">
                <label for="title">标题</label>
                <input type="text" id="title" placeholder="扫码挪车" value="扫码挪车" />
            </div>
            <div class="input-group">
                <div class="checkbox-container">
                    <input type="checkbox" id="enableSubtitle" />
                    <label for="enableSubtitle">添加小标题</label>
                </div>
                <input type="text" id="subtitle" placeholder="扫码联系车主或拨打电话: 16800000000" disabled />
            </div>
            <div class="button-group">
                <button class="primary-button" onclick="generateQrCode()">
                    <i class="fas fa-qrcode"></i> 生成二维码
                </button>
            </div>
            <div class="qr-code-container" style="display: none">
                <img alt="挪车码" />
                <div class="action-buttons">
                    <a target="_blank" class="preview-link">
                        <i class="fas fa-external-link-alt"></i> 预览
                    </a>
                    <a class="download-link">
                        <i class="fas fa-download"></i> 下载
                    </a>
                </div>
                <div class="alert alert-warning mt-2">
                    <i class="fas fa-clock"></i> 请注意:生成的文件仅保留2分钟,请及时下载。
                </div>
            </div>
        </div>
    }
    else
    {
        <div class="card">
            <div class="card-header">
                <i class="fas fa-car"></i>
                <h1 class="title">临时停靠,请多关照</h1>
            </div>
            <div class="card-body">
                <p class="description">如果我的车阻碍了您的车辆通行,点击下方按钮通知我,给您带来不便敬请谅解。</p>
                <a class="phone-button" href="tel:@_decodePhone">
                    <i class="fas fa-phone-alt"></i> 拨打车主电话
                </a>
                <a class="generate-link" href="/nuoche">去生成一个挪车码</a>
            </div>
        </div>
    }
</div>

This implementation has two main functional pages:

      • Generation page **: When the user directly accesses/nuoche, the QR code generation interface is displayed, allowing you to enter your mobile phone number and title
      • Moving the car page **: When the user scans and accesses through the QR code (with p parameter), the interface to make the car owner's phone call with one click is displayed

Through this design, we have realized the complete life cycle of QR codes: generation, scanning, and contact, providing users with a convenient solution for moving cars.

After scanning the code, the detailed information page will be displayed:

扫码后显示截图

3. Online version Core JavaScript Interaction

async function generateQrCode() {
    const title = document.getElementById('title').value;
    const phoneNumber = document.getElementById('phoneNumber').value;
    const enableSubtitle = document.getElementById('enableSubtitle').checked;
    let subtitle = null;
    
    if (enableSubtitle) {
        subtitle = document.getElementById('subtitle').value.trim();
        if (!subtitle) {
            subtitle = `扫码联系车主或拨打电话: ${phoneNumber || "16800000000"}`;
            document.getElementById('subtitle').value = subtitle;
        }
    }

    if (!title || !phoneNumber) {
        alert('请输入标题和手机号码');
        return;
    }

    try {
        const response = await fetch('/api/Image/nuoche', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                title: title,
                phoneNumber: phoneNumber,
                subtitle: subtitle
            })
        });

        const data = await response.json();
        if (data.success) {
            const qrCodeContainer = document.querySelector('.qr-code-container');
            const img = qrCodeContainer.querySelector('img');
            img.src = data.qrCodeUrl;
            qrCodeContainer.querySelector('.preview-link').href = data.generatedUrl;

            // 添加下载功能
            const downloadLink = qrCodeContainer.querySelector('.download-link');
            downloadLink.onclick = () => {
                const a = document.createElement('a');
                a.href = data.qrCodeUrl;
                a.download = '挪车码.png';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
            };

            qrCodeContainer.style.display = 'block';
        } else {
            throw new Error(data.message);
        }
    } catch (error) {
        console.error('生成二维码失败:', error);
        alert('生成二维码失败,请稍后重试');
    }
}

// 添加小标题复选框的事件处理
document.addEventListener('DOMContentLoaded', function() {
    const enableSubtitleCheckbox = document.getElementById('enableSubtitle');
    const subtitleInput = document.getElementById('subtitle');
    const phoneInput = document.getElementById('phoneNumber');
    
    if (enableSubtitleCheckbox && subtitleInput) {
        enableSubtitleCheckbox.addEventListener('change', function() {
            subtitleInput.disabled = !this.checked;
            if (this.checked) {
                if (!subtitleInput.value.trim()) {
                    const phoneNumber = phoneInput.value.trim() || "16800000000";
                    subtitleInput.value = `扫码联系车主或拨打电话: ${phoneNumber}`;
                }
                subtitleInput.focus();
            }
        });
        
        // 当手机号码变化时,如果小标题已启用且使用的是默认格式,则更新小标题中的电话号码
        phoneInput.addEventListener('input', function() {
            if (enableSubtitleCheckbox.checked && subtitleInput.value.startsWith('扫码联系车主或拨打电话:')) {
                const phoneNumber = this.value.trim() || "16800000000";
                subtitleInput.value = `扫码联系车主或拨打电话: ${phoneNumber}`;
            }
        });
    }
});

在线版本的后端API实现与离线版类似,都是使用相同的核心二维码生成逻辑,但增加了文件上传处理、临时存储和清理等功能,这里不再细述,在线版源码戳这,挪车二维码接口定义如下:

[HttpPost("nuoche")]
[AllowAnonymous]
public async Task<IActionResult> NuoCheAsync([FromBody] NuoCheRequest request,
    [FromServices] IWebHostEnvironment env,
    [FromServices] IOptions<SiteOption> siteOption)
{
    try
    {
        if (string.IsNullOrWhiteSpace(request.Title) || string.IsNullOrWhiteSpace(request.PhoneNumber))
        {
            return BadRequest(new { success = false, message = "标题和手机号码不能为空" });
        }

        if (!long.TryParse(request.PhoneNumber, out long phoneNumberLong))
        {
            return BadRequest(new { success = false, message = "无效的手机号码" });
        }

        var encodedPhone = new Hashids("codewf").EncodeLong(phoneNumberLong);
        var generatedUrl = $"{siteOption.Value.Domain}/nuoche?p={encodedPhone}";

        var fileName = $"qrcode_{Guid.NewGuid():N}.png";
        var qrCodePath = Path.Combine(env.WebRootPath, IconFolder, fileName);

        Directory.CreateDirectory(Path.Combine(env.WebRootPath, IconFolder));

        QrCodeGenerator.GenerateQrCode(request.Title, generatedUrl, qrCodePath, request.SubTitle);

        var qrCodeUrl = $"/{IconFolder}/{fileName}";
        return Ok(new
        {
            success = true,
            qrCodeUrl,
            generatedUrl
        });
    }
    catch (Exception ex)
    {
        return BadRequest(new { success = false, message = ex.Message });
    }
}

5. Function comparison and application scenarios

The offline desktop version and the online web version each have their own advantages. The following is a comparison of their characteristics:

function Offline version online edition
installation requirements Need to download and install No installation required, browser access
platform support Windows、macOS、Linux any modern browser
Internet dependence Only the network is required for initial URL generation Completely dependent on the Internet
file storage Local permanent storage Server temporary save
UI experience Desktop application style responsive web design
Drag and drop support Support dragging QR codes Direct drag and drop is not supported
Privacy Protection High (local processing) Medium (server processing)
subtitle function Support custom subtitles Support custom subtitles

The addition of the subtitle function makes the QR code more information-rich. Additional prompt information can be added under the QR code, such as "Scan the code to contact the car owner" or display some contact information, which enhances the identifiability and convenience of use of the QR code.

6. Summary and Outlook

Through this article, we introduce in detail the development process of the mobile QR code generation tool, including requirements analysis, core code implementation, UI design and multi-platform deployment. This tool not only solves the privacy disclosure and number abuse problems caused by traditional mobile contact methods, but also provides a safer and more convenient mobile experience through modern technology.

This tool is particularly useful in the following scenarios:

      • Temporary parking **: Provide contact information when temporarily parking in communities, shopping malls, etc.
      • Auto Show Event **: Place a QR code for easy contact when displaying vehicles
      • Shared parking space **: Provide temporary contact information in private parking spaces
      • Emergency **: When the vehicle needs to contact the owner urgently due to special circumstances

In the future, we plan to further improve this tool. Possible improvement directions include:

      • Multi-language support **: Add English, Japanese and other multi-language interfaces to facilitate international users
      • More customization options **: Support customization of QR code colors, styles and layout
      • Statistics function **: Add statistics on the number of scanning codes to help users understand the usage of QR codes
      • Enterprise version functions **: Provide batch generation functions for enterprise users such as fleet management and parking lots

As a utility tool, the Mobile QR Code Generator solves practical problems in real life, while also demonstrating how to use the modern. NET technology stack to build cross-platform applications.

I hope this article will be helpful to you. If you have any questions, please leave a comment area to discuss it!

Source code reference:

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2/25/2025

NET 10 Preview 1 released

Today. NET 10 Preview 1 was released. I downloaded it as soon as possible and upgraded the Avalonia UI project and blog site. The former's functional testing and AOT release were normal, the latter's debugging was normal, and Docker was not successful for the time being.

继续阅读