生成QR码

时间:2014-07-15 21:58:13

标签: c# wpf qr-code

我正在开展一个项目,我希望能够在屏幕上向用户显示QR码。

我正在使用从http://qrcodenet.codeplex.com/生成的QR码生效,但我只找到了将QR码写入文件的方法,这正是我想要的。

相反,我希望图像显示在WPF窗口的控件中,但我不想创建文件,然后将图像源设置为新创建文件的图像控件。这似乎有点过分,所以我希望有可能将流直接放入图像控件而不是文件中。

以下是我到目前为止的代码。

private void generateQRCode()
        {
            QrEncoder encoder = new QrEncoder(ErrorCorrectionLevel.M);
            QrCode qrCode;
            encoder.TryEncode("Test", out qrCode);

            DrawingBrushRenderer dRenderer = new DrawingBrushRenderer(
                new FixedModuleSize(2, QuietZoneModules.Two), System.Windows.Media.Brushes.Black, 
                    System.Windows.Media.Brushes.White);

            DrawingBrush dBrush = dRenderer.DrawBrush(qrCode.Matrix);
            System.Windows.Shapes.Rectangle rect = new System.Windows.Shapes.Rectangle();
            rect.Width = 150;
            rect.Height = 150;
            rect.Fill = dBrush;

            MemoryStream ms = new MemoryStream();
            dRenderer.WriteToStream(qrCode.Matrix, ImageFormatEnum.PNG, ms, new System.Windows.Point(96, 96));

            var image = new System.Drawing.Bitmap(System.Drawing.Image.FromStream(ms), new System.Drawing.Size(new System.Drawing.Point(200, 200)));

            image.Save("myImage.png", System.Drawing.Imaging.ImageFormat.Png);

        }

基本上,我想替换image.save()函数,以便图像直接显示在我的应用程序GUI上的控件中,而不是写入单独的文件。

感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:3)

我实际上从来没有在WPF中写过任何东西,所以这可能是错的,但你可能想做this之类的事情。我将从下面的问题中复制答案:

using(MemoryStream memory = new MemoryStream())
{
    image.Save(memory, ImageFormat.Png);
    memory.Position = 0;
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.BeginInit();
    bitmapImage.StreamSource = memory;
    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    bitmapImage.EndInit();
}

然后,我假设您可以将BitmapImage与用于显示图像的任何控件相关联。

答案 1 :(得分:1)

您可以在此处找到答案:Using Image control in WPF to display System.Drawing.Bitmap

System.Drawing中的HBipmaps不能直接在WPF中使用。 Lars Truijens在他的帖子上解释,但看到下面帖子的剪辑:

根据http://khason.net/blog/how-to-use-systemdrawingbitmap-hbitmap-in-wpf/

   [DllImport("gdi32")]
   static extern int DeleteObject(IntPtr o);

   public static BitmapSource loadBitmap(System.Drawing.Bitmap source)
   {
       IntPtr ip = source.GetHbitmap();
       BitmapSource bs = null;
       try
       {
           bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip, 
              IntPtr.Zero, Int32Rect.Empty, 
              System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
       }
       finally
       {
           DeleteObject(ip);
       }

       return bs;
   }

它获取System.Drawing.Bitmap(来自WindowsBased)并将其转换为BitmapSource,它实际上可以用作WPF中Image控件的图像源。

image1.Source = YourUtilClass.loadBitmap(SomeBitmap);

答案 2 :(得分:0)

使用包QrCode.Net(Install-Package QrCode.Net),我们可以生成qrcode内容的矩阵数据,所以我用矩阵数据进行了WPF控制。

QRCode.xaml

<UserControl x:Class="WpfApp1.QRCode"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfApp1"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
    <ItemsPanelTemplate x:Key="HorizontalPanel">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"/>
    </ItemsPanelTemplate>
    <DataTemplate x:Key="PointTemplate">
        <Rectangle Fill="{Binding Color}" Width="{Binding Size, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" Height="{Binding Size, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
    </DataTemplate>
    <DataTemplate x:Key="LineTemplate">
        <ItemsControl ItemsSource="{Binding}" ItemsPanel="{StaticResource HorizontalPanel}" ItemTemplate="{StaticResource PointTemplate}">
        </ItemsControl>
    </DataTemplate>
</UserControl.Resources>
<Grid>
    <ItemsControl Name="qrcodeControl" HorizontalAlignment="Center" VerticalAlignment="Center"
                ItemTemplate="{StaticResource LineTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel></StackPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>

QRCode.xaml.cs

using Gma.QrCodeNet.Encoding;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for QRCode.xaml
    /// </summary>
    public partial class QRCode : UserControl, INotifyPropertyChanged
    {
        public QRCode()
        {
            InitializeComponent();

            //default point size
            this.Size = 3;
            qrcodeControl.ItemsSource = QRMatrix;
        }

        private ObservableCollection<ObservableCollection<QrCodePoint>> qrMatrix = new ObservableCollection<ObservableCollection<QrCodePoint>>();
        ObservableCollection<ObservableCollection<QrCodePoint>> QRMatrix
        {
            get
            {
                return this.qrMatrix;
            }
        }

        public new static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
            "Content",
            typeof(string),
            typeof(QRCode),
            new UIPropertyMetadata((s, e) =>
            {
                QRCode dp = s as QRCode;
                dp.QRMatrix.Clear();
                dp.Generate(e.NewValue.ToString()).ForEach(
                    line =>
                    {
                        ObservableCollection<QrCodePoint> linePoints = new ObservableCollection<QrCodePoint>();
                        dp.qrMatrix.Add(linePoints);
                        foreach (var point in line)
                        {
                            linePoints.Add(point);
                        }
                    });
                dp.RaisePropertyChanged("Content");
            }));

        public new string Content
        {
            get { return (string)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }

        public static readonly DependencyProperty SizeProperty = DependencyProperty.Register(
            "Size",
            typeof(double),
            typeof(QRCode),
            new UIPropertyMetadata((s, e) =>
            {
                QRCode dp = s as QRCode;
                dp.RaisePropertyChanged("Size");
            }));

        public double Size
        {
            get { return (double)GetValue(SizeProperty); }
            set { SetValue(SizeProperty, value); }
        }

        public List<QrCodePoint[]> Generate(string content)
        {
            List<QrCodePoint[]> result = new List<QrCodePoint[]>();
            QrEncoder encoder = new QrEncoder(ErrorCorrectionLevel.M);
            QrCode qrCode;
            encoder.TryEncode(content, out qrCode);

            for (int i = 0; i < qrCode.Matrix.Height; i++)
            {
                var line = new QrCodePoint[qrCode.Matrix.Width];
                result.Add(line);
                for (int j = 0; j < qrCode.Matrix.Width; j++)
                {
                    line[j] = new QrCodePoint() { Color = qrCode.Matrix[i, j] ? Brushes.Black : Brushes.White };
                }
            }

            return result;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class QrCodePoint
    {
        public SolidColorBrush Color { get; set; }
    }
}

和MainWindow使用此WPF控件

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    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:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <local:QRCode Grid.Column="1" Size="5" Content="Hello, world!"></local:QRCode>
</Grid>

相关问题