我正在开展一个项目,我希望能够在屏幕上向用户显示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上的控件中,而不是写入单独的文件。
感谢您提供的任何帮助。
答案 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>