V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
7sDream
V2EX  ›  Python

艺术二维码 QArt Codes

  7sDream ·
7sDream · 2016-08-06 11:38:03 +08:00 · 22724 次点击
这是一个创建于 3062 天前的主题,其中的信息可能已经有所发展或是发生改变。

介绍

呼,这个很久之前定的目标今天终于差不多算写出来了。

几个月之前发现了一篇文章,是 Russ Cox 写的一篇关于将二维码与图片结合的,我觉得很好玩就准备动手实现。

其实已经有了其他实现的,我记得代码家的微博好像还推荐过,就是这个:https://github.com/dieforfree/qart4j

所以可能很多人都知道这个东西了,我读完 qart4j 的代码( QwQ ,好难读,没注释,而且我还不会 Java )之后开始用 Python 实现我自己的版本,其他的就不多说了,看几个例子:

例子

扫描这个二维码就能打开 V2EX 的首页啦~~

这个是我的 Github

这个是 bilibili

啊对了,需要说明的是,二维码的编码部分也是我自己写的,没有调用库,独立出来了一个 pyqr 的 cli 用于生成普通的二维码,使用效果大概是这样:

当然,也是可以生成图片的,加个 -o 参数就好

pyqart 的 cli 也支持打印在 terminal 里的,例子:

其他的细节看 Readme 吧,pyqr -hpyqart -h 可以查看更多帮助。

原理

因为有点复杂我就不在帖子里说了,涉及到二维码的编码规范和里德所罗门纠错码之类的东西,大家可以暂时看上面那篇算法提出者写的文章,有可能以后我会写一系列文章仔细说明这个实现。

代码

代码在这: https://github.com/7sDream/pyqart

扫描下面这个二维码也可以访问:

我的其他项目可以在 Github 上看……除了那两个最先的 piano 项目,其他的都挺好玩儿的……

额外

额,开学就大四了,然而工作和实习都并没有着落…………

听说阿里今年几乎就不怎么找人,加上它们也没啥 Py 岗……估计是没戏了。 腾讯扔了个简历至今没回应。 网易那个笔试简直了……算法题死活交不上,最后放弃了

未来迷茫中…………

目前座标天津,大四一年准备尽量出去实习吧,有没有什么北京的公司招 Py 实习的,可以联系一下。还有就是毕业以后的工作,有没有公司要的?

以上,谢谢阅读。

第 1 条附言  ·  2016-08-06 14:17:07 +08:00

本来上午想在我知乎专栏里发篇文章介绍下项目和原理的……然后发现知乎专栏会把上传的包含二维码的图片自动转换成内容……

有点烦这个功能,当时气的不行发了篇文章喷,在这:去你特么的友善度

朋友们可以点进去瞅瞅 =,=

第 2 条附言  ·  2016-08-06 20:24:43 +08:00

如果大家想实现的话,这里有一些可以参考的资料。

最后这是我项目的架构,如果想阅读源码的同学可以参考:

pyqart.qr 这一部分是一个基本上完整的二维码生成器, data 模块是数据编码, ec 模块是生成纠错码, args 是二维码的参数, painter.canvas 生成二维码的框架, painter.painter 的作用是把 canvas 、 data 、 ec 三部分组合起来,最后交给 printer 里的各种生成器输出二维码。

pyqart.art 里的 QArtSourceImage 是处理输入图像的,做一些二值化,dithering,计算对比度之类的操作。 QrArtist 里的 bis 函数是 QArt 的关键算法。

我代码也没注释的,可能也有点难读,推荐和 qart4j 结合起来读。

第 3 条附言  ·  2016-08-06 21:39:13 +08:00
我跑去 Reddit 上也发了下 =,= 然而并没有人鸟我……

https://www.reddit.com/r/Python/comments/4wemoe/qart_codes_python_implementation/

小伙伴们如果有时间的话可以随意留言支持一下~
102 条回复    2018-09-10 10:51:29 +08:00
1  2  
xcodebuild
    1
xcodebuild  
   2016-08-06 11:43:15 +08:00 via Android   ❤️ 1
看着论文就实现出来了简直 6 的不行
Sakuramiku
    2
Sakuramiku  
   2016-08-06 11:45:18 +08:00
不愧是我 77..
7sDream
    3
7sDream  
OP
   2016-08-06 11:45:24 +08:00
@codefalling 还是参考了原作者的实现和 java 的实现的……
designer
    4
designer  
   2016-08-06 11:54:25 +08:00
虽然这个早就有了但是还是要支持一下!
zhujinliang
    5
zhujinliang  
   2016-08-06 11:54:51 +08:00
赞!比二维码中间抠个洞的做法高到不知哪里去了
7sDream
    6
7sDream  
OP
   2016-08-06 11:55:56 +08:00
@designer 是的,自己实现一下搞懂原理也挺好~
7sDream
    7
7sDream  
OP
   2016-08-06 11:56:12 +08:00
@zhujinliang

OvO 谢谢支持~
kylinking
    8
kylinking  
   2016-08-06 12:07:26 +08:00 via iPhone
可以,支持一下~
sobigfish
    9
sobigfish  
   2016-08-06 12:22:57 +08:00
url 里 #后面的是故意的还是编码的问题 anyway 很牛
7sDream
    10
7sDream  
OP
   2016-08-06 12:25:15 +08:00
@sobigfish

故意的,因为总要有数据把二维码填满才能做到控制二维码的样子呀,基本原理就是改变这一串锚点来拟合成目标图片。可以看原作者的文章了解原理~~
ynyounuo
    11
ynyounuo  
   2016-08-06 12:42:10 +08:00
@7sDream
不知道这种能不能用代码实现
ahonn
    12
ahonn  
   2016-08-06 12:48:34 +08:00
77 真棒
7sDream
    13
7sDream  
OP
   2016-08-06 12:56:29 +08:00
@ynyounuo

这个……难度就有点大了…估计是利用了二维码扫描软件的一些特性 比如点不一定需要是正方形…颜色也不用相同等等…需要针对生成的二维码单独设计吧…而且还是动图…纯用代码估计悬
Jaylee
    14
Jaylee  
   2016-08-06 13:39:14 +08:00
@ahonn 这个好厉害
meunicorn
    15
meunicorn  
   2016-08-06 13:44:10 +08:00
好强。。。
iLionel
    16
iLionel  
   2016-08-06 13:47:26 +08:00
应该是叫做 Halftone QR Codes
7sDream
    17
7sDream  
OP
   2016-08-06 13:49:23 +08:00
@meunicorn

其实原理的提出者才是真的强~我只是写了个实现而已
7sDream
    18
7sDream  
OP
   2016-08-06 13:49:46 +08:00
@iLionel

http://research.swtch.com/qart

原作者的文章里定了名字咯~~没办法呀
UnisandK
    19
UnisandK  
   2016-08-06 13:51:11 +08:00
https://github.com/chinuno-usami/CuteR
这个更好看,可以读读代码
7sDream
    20
7sDream  
OP
   2016-08-06 14:04:46 +08:00
@UnisandK

我看了一下图,原理不一样。

注意它的图片里,左上,右上和左下这几个定位图形,外边框的黑色块是标准的 一个点 应该占的宽度。

再看图片里面的哪些小的黑点,明显大小是不一样的。

我猜想它的原理应该是这样,先正常生成一张二维码,然后根据图片的二值化数据,来吧原来的二维码进行修改。比如一个黑点所占的地方,在图片里应该是白色,它就把这个点分为 9 份,中间的留黑,周围变白。而扫描仪扫描的时候先按点应该的大小扫到这个点,然后优先判断中心部分的颜色。所以变化后的二维码还能扫描出来。

这个思路也很不错来着~~我下午去看看代码,看跟我想的一样不……

话说给我二维码上色这个我也准备写来着~
cfans1993
    21
cfans1993  
   2016-08-06 14:11:15 +08:00
忍不住打开微信扫了一下 ,棒棒的
7sDream
    22
7sDream  
OP
   2016-08-06 14:11:54 +08:00   ❤️ 1
@cfans1993 嘿嘿~~感谢支持~~
passion336699
    23
passion336699  
   2016-08-06 14:19:52 +08:00 via Android
厉害👍
meunicorn
    24
meunicorn  
   2016-08-06 14:34:31 +08:00
@7sDream 👍看论文就把东西撸了出来也很强
MyFaith
    25
MyFaith  
   2016-08-06 14:54:55 +08:00
不错,已 star
jyhmijack
    26
jyhmijack  
   2016-08-06 15:00:48 +08:00
有木有兴趣来陌陌,在北京 --
7sDream
    27
7sDream  
OP
   2016-08-06 15:06:56 +08:00
@jyhmijack

OvO 是说实习还是工作?
7sDream
    28
7sDream  
OP
   2016-08-06 15:09:54 +08:00
@MyFaith Thanks~
jyhmijack
    29
jyhmijack  
   2016-08-06 15:10:50 +08:00
@7sDream 实习+工作咯 -。-
7sDream
    30
7sDream  
OP
   2016-08-06 15:14:30 +08:00
@jyhmijack

实习还是有兴趣哒~~但是工作因为这学期还有校招,所以还在看~~

邮箱: [email protected]

邮件联系吧~
jyhmijack
    31
jyhmijack  
   2016-08-06 15:20:58 +08:00
@7sDream 发你咯
skydiver
    32
skydiver  
   2016-08-06 15:58:49 +08:00 via iPad
转换二维码成 URL 不是为了解决手机没法识别二维码的问题(那样的话只在手机版转换就行了,没必要 web 也转换),而是因为很多答案后面都附加了额外的二维码看起来很影响观感,好多二维码很大占了半屏幕之类的,变成 URL 就整洁多了。

知乎更好的做法是鼠标点一下还是可以显示原图之类。
7sDream
    33
7sDream  
OP
   2016-08-06 16:01:51 +08:00
@skydiver

恩,也有这种可能吧。

不过还是懒,明明可以加个用户设置的,或者按你说的加个显示原图的功能,一刀切只能用文字的做法真的有点蠢。
zeac
    34
zeac  
   2016-08-06 16:03:11 +08:00
@designer 看到你的邮件了
manhere
    35
manhere  
   2016-08-06 16:07:06 +08:00
不错,就是后面的参数太长了
7sDream
    36
7sDream  
OP
   2016-08-06 16:13:33 +08:00
@manhere

感谢支持~~这也是没办法的呀,必须要有数据才能把二维码模拟成想要的样子呀~
fashioncj
    37
fashioncj  
   2016-08-06 16:14:39 +08:00
@ynyounuo 山大学线的?
cuminflea
    38
cuminflea  
   2016-08-06 17:35:01 +08:00 via iPad
7sDream
    39
7sDream  
OP
   2016-08-06 17:38:13 +08:00
@cuminflea

这个应该就是上面 @UnisandK 提到的那个 CuteR 项目用的原理~和 QArt 原理不一样

Halftone 是在生成图片后进行处理, QArt 是直接生成出和图片相似的

不过那个也挺好玩的,有时间我研究一下~
Maic
    40
Maic  
   2016-08-06 17:40:39 +08:00
仰望大神
chinuno
    41
chinuno  
   2016-08-06 17:49:27 +08:00 via Android
。你说的没错。我就相当于把点缩小了放图上而已。感觉你这样做出来的要比我干净一些,不过包含了太多垃圾信息扫出来看到后面那坨也难受
no13bus
    42
no13bus  
   2016-08-06 17:52:51 +08:00
天津啥学校的? 很厉害. 支持 python
7sDream
    43
7sDream  
OP
   2016-08-06 17:54:15 +08:00
@chinuno

是的,是两种不同的思路来着~~

恩,确实 QArt 这种方式后面必须要加入很多无用的信息,还好网址后面跟锚点不影响访问。

所以 QArt 这种方法仅限于处理包含 URL 的二维码,限制比较大, 你的那种方法适用性比较广。
7sDream
    44
7sDream  
OP
   2016-08-06 17:55:41 +08:00
@no13bus 南开的。
ynyounuo
    45
ynyounuo  
   2016-08-06 18:10:50 +08:00
@fashioncj 不知道,原来在朋友圈一个公众号上见到的
nyanyh
    46
nyanyh  
   2016-08-06 18:11:42 +08:00
失望,连是谁都看不出来了

#手动滑稽
7sDream
    47
7sDream  
OP
   2016-08-06 18:13:14 +08:00
@nyanyh 可以把 -v 参数调高一点~~
em2046
    48
em2046  
   2016-08-06 18:29:36 +08:00
膜拜大神
plqws
    49
plqws  
   2016-08-06 18:39:52 +08:00
@nyanyh 真正的粉丝还是看得出来的
giuem
    50
giuem  
   2016-08-06 18:55:53 +08:00 via iPhone
@7sDream 动图之前有 v 友实现了 /t/264254
giuem
    51
giuem  
   2016-08-06 18:58:01 +08:00 via iPhone
@giuem 没仔细看,好像和楼上那位说的不一样。。。
7sDream
    52
7sDream  
OP
   2016-08-06 19:04:01 +08:00
@giuem 诶 虽然不一样但是这个动态二维码也很好玩呀!果然 v 友创意无限~
aljun
    53
aljun  
   2016-08-06 19:11:17 +08:00 via iPhone
用力抱紧 7s 大腿(・∀・)
coreki
    54
coreki  
   2016-08-06 19:14:57 +08:00 via iPhone
自己实现了,厉害。这种缩小点位后的二维码有更多空间填充图形,比普通二维码有个性多了,
7sDream
    55
7sDream  
OP
   2016-08-06 19:33:28 +08:00
@coreki 谢谢支持~我也是觉得这想法好玩才有动力去实现它的~
ynyounuo
    56
ynyounuo  
   2016-08-06 19:41:35 +08:00
这怎么难得倒真正的粉丝?李嘉诚也太好认了啊!
scola
    57
scola  
   2016-08-06 19:46:01 +08:00 via Android
厉害~我也看了那个论文~但是没弄懂~可能是我对 QR 码的基础不太了解~期待你的后续怎样
scola
    58
scola  
   2016-08-06 19:48:13 +08:00 via Android
后续怎样→后续文章

能说一下要看懂那篇论文需要什么基础知识么?
huybery
    59
huybery  
   2016-08-06 20:02:16 +08:00
我来晚了呀
cholerae
    60
cholerae  
   2016-08-06 20:05:28 +08:00
77 好棒
7sDream
    61
7sDream  
OP
   2016-08-06 20:18:45 +08:00
@scola

恩,看懂那篇论文确实需要一些基础知识。

首先要搞懂二维码的生成原理,我推荐 coolshell 的[这篇文章]( http://coolshell.cn/articles/10590.html) 看完之后再去看 QArt 那篇论文应该能把前半部分(到 Gauss-Jordan Elimination 这一节之前)看懂。

后面的部分是一些数学知识,有点难度,包括多项式除法,伽罗华域,里德所罗门码,向量空间,基,行列式变换之类的知识。

这一段东西我是网上各种搜索的,现在一时也找不全之前看的了,但是[这一篇]( http://netclass.csu.edu.cn/NCourse/hep104/course/content.html)是我看的里面讲的比较清楚的。读第 16.2 这一节就差不多了。

然后再去看 QArt 文章 Gauss-Jordan Elimination 和之后部分,应该差不多能把原理弄懂了。

至于实现的时候我推荐[这个网站]( http://www.thonky.com/qr-code-tutorial/),这个网站一步一步的教你怎么弄出一个二维码。然后你还需要一个二维码的标准。因为我英文不太好,我是 ISO:18004 和 GB/T 18284 一起看的,这两篇标准都能 Google 到我就不发了。

另外强烈建议还是阅读一下别人的实现,一边看标准一边看代码可以互相参考,便于理解。

我代码里 pyqart.qr 这一部分是一个基本上完整的二维码生成器, data 模块是数据编码, ec 模块是生成纠错码, args 是二维码的参数, painter.canvas 生成二维码的骨架, painter.painter 的作用是把 canvas 、 data 、 ec 三部分组合起来,最后交给 printer 里的各种生成器输出二维码。 pyqart.art 里的 QrArtist 里的 bis 函数是 QArt 的关键算法。我代码的架构大概就是这样了,你可以读读以做参考。(我代码也没注释的,可能也有点难读,你可以和 qart4j 结合起来读)
7sDream
    62
7sDream  
OP
   2016-08-06 20:25:42 +08:00
@scola

由于回复的时候输入法有点问题……所以链接都 boom 了。我刚刚把要用到的链接都 append 了一下,可以去那里看。
imeoer
    63
imeoer  
   2016-08-06 20:30:02 +08:00
太赞啦,大概试了几次 url 没有扫出来,我再试试
7sDream
    64
7sDream  
OP
   2016-08-06 20:33:38 +08:00
@imeoer

咦~不会吧,我用微信和 QQ 都试过,成功率几乎都是 100% 丫~
imeoer
    65
imeoer  
   2016-08-06 20:40:40 +08:00
@7sDream 哈哈,试了黑色能完美识别,示例的淡蓝色一直不行(微信 /QQ )
7sDream
    66
7sDream  
OP
   2016-08-06 20:46:33 +08:00
@imeoer

确实, QQ 试有个蓝色的一直不行…… =,=

看来必须得放弃我喜爱的天依蓝了……我去换个好识别的颜色~
imeoer
    67
imeoer  
   2016-08-06 20:54:44 +08:00
@7sDream 加油 lz ,喜欢写这么有意思的项目工作肯定没问题~
zander
    68
zander  
   2016-08-06 21:03:07 +08:00   ❤️ 2
分享一些更艺术的。



都是 TGFC 一个网友做的,接受定制服务。
7sDream
    69
7sDream  
OP
   2016-08-06 21:04:27 +08:00
@imeoer

我试了一下, QQ 扫描二维码的功能好渣呀……比微信差了一大截……

虽然我试了下,换成深色系的 QQ 的识别成功率也会变高很多……但我决定还是算了,我就喜欢蓝色~

嘻,谢谢鼓励~
7sDream
    70
7sDream  
OP
   2016-08-06 21:05:48 +08:00
@zander

哇!这好酷阿!

不过这些估计得用设计软件对每个二维码单独设计了……好厉害……
zander
    71
zander  
   2016-08-06 21:10:04 +08:00
@7sDream 都是手工作品,不是靠图片 /二维码合成的。
fsp
    72
fsp  
   2016-08-06 21:19:53 +08:00
看到你喷了知乎,然而想说一句知乎是招 Py 实习的,在北京,有兴趣请投递 [email protected] ,逃。。。
Exin
    73
Exin  
   2016-08-06 21:23:16 +08:00
7sDream
    74
7sDream  
OP
   2016-08-06 21:36:38 +08:00
@fsp

尴尬 ing 。=,= 虽然说小喷了一下知乎,但是如果不关心,根本喷都不会喷丫……

主要问题不是这个……主要是吧,如果你看看我 github 就会发现,我有两三个项目是和知乎有关的,一个是通过解析 PC 端网页做的 API ,第二个是基于前面这个做的给关注者自动发私信,第三个更是把你们 Android 客户端的 OAuth 2 的协议 Crack 了做了个 API …………要是真去投知乎我总感觉有那么一点尴尬 =,= 毕竟以前是干坏事的……但其实也有好处,比如对知乎的 RESTful 接口和业务比较熟悉什么的……

还是谢谢告知了,正在考虑中。知乎私信我也收到了,如果投的话我会私信联系你滴~ Thx
fsp
    75
fsp  
   2016-08-06 21:42:14 +08:00   ❤️ 1
@7sDream 点开 github 看了一下,满眼 zhihu ,这还不是真爱么,哈哈
revol
    76
revol  
   2016-08-06 22:51:19 +08:00
高德招 python ,阿里巴巴旗下的哦
ragnaroks
    77
ragnaroks  
   2016-08-06 23:06:55 +08:00
ragnaroks
    78
ragnaroks  
   2016-08-06 23:08:16 +08:00
google 图片来源关键字 二维码 暴力
7sDream
    79
7sDream  
OP
   2016-08-06 23:11:02 +08:00
@ragnaroks

这个应该是用 @chinuno 的 [CuteR]( https://github.com/chinuno-usami/CuteR) 项目做的,效果也很棒
7sDream
    80
7sDream  
OP
   2016-08-06 23:11:45 +08:00
@revol

有木有链接扔一个?
ragnaroks
    81
ragnaroks  
   2016-08-06 23:21:19 +08:00
@7sDream 看了一下,很不错,以后可以用青蛙做头像了
qq915458022
    82
qq915458022  
   2016-08-06 23:31:29 +08:00 via Android
支持一个
RobertYang
    83
RobertYang  
   2016-08-06 23:38:32 +08:00 via Android
马克下,明天看
Phariel
    84
Phariel  
   2016-08-06 23:43:46 +08:00 via Android
@ragnaroks 闷声发大财才是最吼滴
no13bus
    85
no13bus  
   2016-08-07 00:10:16 +08:00
@7sDream 哈哈.支持, 我隔壁学校的
7sDream
    86
7sDream  
OP
   2016-08-07 00:14:59 +08:00
@no13bus 可以可以,感谢支持~
Geeker
    87
Geeker  
   2016-08-07 00:59:46 +08:00
看着论文就实现出来了简直 6 的不行 +1
cuminflea
    88
cuminflea  
   2016-08-07 04:24:28 +08:00 via iPad
@7sDream 带我一起做点好玩的吧
scola
    89
scola  
   2016-08-07 08:01:55 +08:00 via Android
谢谢回复~我去学习一下
ariza
    90
ariza  
   2016-08-07 10:54:00 +08:00
滋辞
zzczzc
    91
zzczzc  
   2016-08-07 14:23:34 +08:00
挺棒的
zjyjer
    92
zjyjer  
   2016-08-08 00:19:43 +08:00
腾讯投简历是找人内推了?
7sDream
    93
7sDream  
OP
   2016-08-08 00:28:16 +08:00
@zjyjer 没 并没有熟人在腾讯 所以只是正常的投了份校招简历
Sunyanzi
    94
Sunyanzi  
   2016-08-08 00:53:42 +08:00
二维码可玩的东西太多了 ... 另一种玩法可以参考我头像 ...
zjyjer
    95
zjyjer  
   2016-08-08 11:48:08 +08:00   ❤️ 1
@7sDream 作为隔壁的同学 愿意友情帮你推一下 考虑发份简历到 zjyjer AT gmail.com ?或者邮件提供下姓名、手机号、邮箱也可以
7sDream
    96
7sDream  
OP
   2016-08-08 12:15:54 +08:00
@zjyjer 感谢感谢~~已发 OvO
Allianzcortex
    97
Allianzcortex  
   2016-08-08 15:45:42 +08:00
厉害厉害
Allianzcortex
    98
Allianzcortex  
   2016-08-08 16:16:42 +08:00
同为 Python 党,话说回来当时还给 zhihu-python 提了个 PR,当时学习的时候 py2 还是主流,突然间大家就都转向 py3 了。 Django 文档翻译?其实看 Django 1.9 的文档那段期间是英语水平提升最快的一个阶段 haha ~~看 CSAPP 里面的英文还是学术了点。

不知道有没有兴趣来我们公司呢?虽然达不到 BAT 级别,但我们有 T-star 计划啊:-D (找了一个比较随便的 [链接]( http://sse.ustc.edu.cn/pages/xxll.php?newsid=1200))确实厉害,比我大三的时候棒多了。 Python 在数据挖掘和运维上都有很大应用,简历请发 @mailto:[email protected]
Allianzcortex
    99
Allianzcortex  
   2016-08-09 14:32:06 +08:00
木有兴趣么?。。。
7sDream
    100
7sDream  
OP
   2016-08-09 15:26:29 +08:00
@Allianzcortex

第一份工作的话还是准备尽量努力进一些大公司吧,毕竟多学点经验嘛。抱歉辣~
1  2  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3663 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 26ms · UTC 00:50 · PVG 08:50 · LAX 16:50 · JFK 19:50
Developed with CodeLauncher
♥ Do have faith in what you're doing.