您的位置:首页 > 其它

通通WPF随笔(3)——艺术二维码素材生成器

2013-05-23 15:57 232 查看
  最近公司让我开发一个条形码的生成控件,花了半天时间搞定觉得不过瘾,什么年代了该用二维码了吧。于是wiki了一下二维码的资料。

  比较常见的就是QR码(Quick Response)即快速识别码,为了验证“快速”,我特地和条形码做了一次比较:经过我测试条形码的code 128编码方式可以表示数字、字母、和符号,而且长度也可以很长。当我用“我查查”进行识别测试时发现,当长度达到20个字符时就很难识别出来了,速度也比较慢,也许是软件的原因吧。但二维码不同,其中包括了汉字等乱七八糟的一大堆东西,同样可以秒识。

  看了各种外国设计师的艺术二维码设计让我一发不可收拾。先来欣赏一下国外大师的设计吧:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Gma.QrCodeNet.Encoding;
using Gma.QrCodeNet.Encoding.Windows.Render;
using System.Windows;
using System.Windows.Controls;

namespace QRCodeFactory
{
static class PathRender
{
/// <summary>
/// 以矩形来填充矩阵点
/// </summary>
/// <param name="QrMatrix">算出来的矩阵</param>
/// <param name="xScale">isRandom?随机取值的最小值:每个点的宽度</param>
/// <param name="yScale">isRandom?随机取值的最大值:每个点的高度</param>
/// <param name="isRandom">是否随机大小</param>
/// <returns>返回路径填充材质</returns>
public static StreamGeometry DrawRectGeometry(BitMatrix QrMatrix, double xScale, double yScale, bool isRandom)
{
int width = QrMatrix == null ? 21 : QrMatrix.Width;

StreamGeometry qrCodeStream = new StreamGeometry();
qrCodeStream.FillRule = FillRule.EvenOdd;

if (QrMatrix == null)
return qrCodeStream;

using (StreamGeometryContext qrCodeCtx = qrCodeStream.Open())
{
for (int y = 0; y < width; y++)
{
for (int x = 0; x < width; x++)
{
if (QrMatrix[x, y])
{
if (isRandom)
qrCodeCtx.DrawRectGeometry(x, y, (double)(new Random(x + y + Environment.TickCount).Next((int)(xScale * 100), (int)(yScale * 100))) / 100, (double)(new Random(x + y + Environment.TickCount).Next((int)(xScale * 100), (int)(yScale * 100))) / 100);
else
qrCodeCtx.DrawRectGeometry(x, y, xScale, yScale);
}
}
}
}

qrCodeStream.Freeze();

return qrCodeStream;
}

/// <summary>
/// 以圆点来填充矩阵点
/// </summary>
/// <param name="QrMatrix">算出来的矩阵</param>
/// <param name="xScale">isRandom?随机取值的最小值:每个点的宽度</param>
/// <param name="yScale">isRandom?随机取值的最大值:每个点的高度</param>
/// <param name="isRandom">是否随机大小</param>
/// <returns>返回路径填充材质</returns>
public static StreamGeometry DrawEllipseGeometry(BitMatrix QrMatrix, double xScale, double yScale, bool isRandom)
{
int width = QrMatrix == null ? 21 : QrMatrix.Width;

StreamGeometry qrCodeStream = new StreamGeometry();
qrCodeStream.FillRule = FillRule.EvenOdd;

if (QrMatrix == null)
return qrCodeStream;

using (StreamGeometryContext qrCodeCtx = qrCodeStream.Open())
{
for (int y = 0; y < width; y++)
{
for (int x = 0; x < width; x++)
{
if (QrMatrix[x, y])
{
if (isRandom)
qrCodeCtx.DrawEllipseGeometry(x, y, (double)(new Random(x + y + Environment.TickCount).Next((int)(xScale * 100), (int)(yScale * 100))) / 100, (double)(new Random(x + y + Environment.TickCount).Next((int)(xScale * 100), (int)(yScale * 100))) / 100);
else
qrCodeCtx.DrawEllipseGeometry(x, y, xScale, yScale);
}
}
}
}

qrCodeStream.Freeze();

return qrCodeStream;
}

/// <summary>
/// 以自定义图形来填充矩阵点
/// </summary>
/// <param name="QrMatrix">算出来的矩阵</param>
/// <param name="xScale">isRandom?随机取值的最小值:每个点的宽度</param>
/// <param name="yScale">isRandom?随机取值的最大值:每个点的高度</param>
/// <param name="isRandomSize">是否随机大小</param>
/// <returns>返回路径填充材质</returns>
public static void DrawCustomGeometry(BitMatrix QrMatrix, ref Grid drawGrid, Path pathGeo, double xScale, double yScale, bool isRandomSize,bool isRandomColor)
{
int width = QrMatrix == null ? 21 : QrMatrix.Width;
drawGrid.Width = drawGrid.Height = width * pathGeo.Width;
for (int y = 0; y < width; y++)
{
for (int x = 0; x < width; x++)
{
if (QrMatrix[x, y])
{
Path newPath = new Path();//创建一个路径,代表一点
newPath.StrokeThickness = 0;
newPath.Stretch = Stretch.UniformToFill;//填充方式s
newPath.HorizontalAlignment = HorizontalAlignment.Left;
newPath.VerticalAlignment = VerticalAlignment.Top;
newPath.Data = pathGeo.Data;
newPath.RenderTransformOrigin = new Point(0.5, 0.5);
TranslateTransform newTTF = new TranslateTransform(x * pathGeo.Width, y * pathGeo.Height);
newPath.RenderTransform = newTTF;
if (isRandomSize)//如果随机大小
{
newPath.Width = newPath.Height = pathGeo.Width * (double)(new Random(x + y + Environment.TickCount).Next((int)(xScale * 100), (int)(yScale * 100))) / 100;
}
else
{
newPath.Width = pathGeo.Width * xScale;
newPath.Height = pathGeo.Height * yScale;
}
if (isRandomColor)//如果随机颜色
newPath.Fill = new SolidColorBrush(GetRandomColor());
else
newPath.Fill = Brushes.Black;

drawGrid.Children.Add(newPath);
}
}
}

}

internal static void DrawRectGeometry(this StreamGeometryContext ctx, double X, double Y, double Width, double Height)
{
ctx.BeginFigure(new Point(X, Y),true, true);
ctx.LineTo(new Point(X, Y + Height), true, true);
ctx.LineTo(new Point(X + Width, Y + Height), true, true);
ctx.LineTo(new Point(X + Width, Y), true, true);
}

internal static void DrawEllipseGeometry(this StreamGeometryContext ctx, double X, double Y, double Width, double Height)
{
X = X * 2;
Y = Y * 2;
Height = Height * 2;
Width = Width * 2;

ctx.BeginFigure(new Point(X, Y + Height / 2), true, true);
ctx.ArcTo(new Point(X + Width, Y + Height / 2), new Size(Width / 2, Height / 2), 90, false, SweepDirection.Clockwise, true, true);
ctx.ArcTo(new Point(X, Y + Height / 2), new Size(Width / 2, Height / 2), 90, false, SweepDirection.Clockwise, true, true);

}

public static Color GetRandomColor()
{
Random randomNum_1 = new Random(Guid.NewGuid().GetHashCode());
System.Threading.Thread.Sleep(randomNum_1.Next(1));
int int_Red = randomNum_1.Next(255);

Random randomNum_2 = new Random((int)DateTime.Now.Ticks);
int int_Green = randomNum_2.Next(255);

Random randomNum_3 = new Random(Guid.NewGuid().GetHashCode());

int int_Blue = randomNum_3.Next(255);
int_Blue = (int_Red + int_Green > 380) ? int_Red + int_Green - 380 : int_Blue;
int_Blue = (int_Blue > 255) ? 255 : int_Blue;

return GetDarkerColor(Color.FromArgb(Convert.ToByte(255),Convert.ToByte(int_Red), Convert.ToByte(int_Green), Convert.ToByte(int_Blue)));
}

//获取加深颜色
public static Color GetDarkerColor(Color color)
{
const int max = 255;
int increase = new Random(Guid.NewGuid().GetHashCode()).Next(30, 255); //还可以根据需要调整此处的值

int r = Math.Abs(Math.Min(color.R - increase, max));
int g = Math.Abs(Math.Min(color.G - increase, max));
int b = Math.Abs(Math.Min(color.B - increase, max));

return Color.FromArgb(Convert.ToByte(255), Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b));
}
}
}


View Code

  下面欣赏一下我心血来潮时设计的:







下载地址:http://files.cnblogs.com/tong-tong/TTQRCodeFactory.zip

后记

  

    自从本人淘宝女装店倒闭以后就一直不甘心,本来想开家店卖下二维码的设计赚点饭钱,结果事太多了,愣是没有时间来装修店铺...各位博友如果有二维码的设计需求的话也可以找我哦,价格公道,只收饭钱~~~~

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: