如何制造像素画
c_legg
·
·
科技·工程
本文受 如何让 DeepSeek 画画 启发。
项目已经开源在 Github 上了,本文中的代码将不再更新,如果有 Bug 请在 Github 上发 issue。
原理
显然我们可以对图片进行分块,在每一块中随机取 k 个点,将它们的颜色的平均值作为这一块的颜色。这也是马赛克的原理。
实现
然后我们从上面那篇文章中学习到了如何用 \LaTeX 画画,所以我就有了这样一个想法:输入一张图片,输出它所对应的像素版本的 \LaTeX:
::::info[pic2tex.py]
import cv2
import math
import random
import sys
import numpy as np
img=cv2.imdecode(np.fromfile(sys.argv[1], dtype=np.uint8), cv2.IMREAD_COLOR)
height=(img.shape)[0]
width=(img.shape)[1]
size=int(sys.argv[2])
print(r"\newcommand{\px}[1]{\color{#1}{\rule{5pt}{5pt}}}")
k=30
for i in range(0, height, math.ceil(height/size)):
for j in range(0, width, math.ceil(width/size)):
r, g, b=0, 0, 0
for _ in range(0, k):
randi=min(i+random.randint(0, math.ceil(height/size)-1), height-1)
randj=min(j+random.randint(0, math.ceil(width/size)-1), width-1)
z, y, x=img[randi, randj]
r+=x/k
g+=y/k
b+=z/k
r=math.floor(r)
g=math.floor(g)
b=math.floor(b)
col='{:02X}{:02X}{:02X}'.format(r, g, b)
print("\\px{"+col.lower()+"}", end="")
if i+math.ceil(height/size)<height:
print("\\\\[-7pt]")
::::
使用方法是在命令行中输入 python pic2tex.py <图片文件> <生成图片尺寸>。
记得下载 python、cv2、numpy。
你可以调整 k 来产生一些不同的效果。
效果
| 原图 |
像素版 |
|
\newcommand{\px}[1]{\color{#1}{\rule{5pt}{5pt}}}\px{ffffff}\px{ffffff}\px{ffffff}\px{fffeff}\px{d4d1d5}\px{8d8691}\px{776e75}\px{605457}\px{6a5e5c}\px{766e73}\px{969099}\px{eae9eb}\px{ffffff}\px{ffffff}\px{ffffff}\px{ffffff}\\[-9pt]\px{ffffff}\px{ffffff}\px{efeeef}\px{807984}\px{7b706a}\px{c0ad80}\px{e5cf7e}\px{c1b070}\px{c0ae6f}\px{e9d582}\px{b9a672}\px{74695e}\px{a4a0a7}\px{fffeff}\px{ffffff}\px{ffffff}\\[-9pt]\px{ffffff}\px{ebeaeb}\px{564d5b}\px{ad9d78}\px{e2cd7a}\px{bead6a}\px{d7c78a}\px{c1ab80}\px{c7b476}\px{b5a269}\px{938450}\px{e9d17c}\px{908165}\px{817b85}\px{fffeff}\px{ffffff}\\[-9pt]\px{ffffff}\px{6d6672}\px{af9d72}\px{dcc877}\px{a89d6e}\px{b8a899}\px{c6b8c3}\px{a49fb8}\px{9299b3}\px{7c8099}\px{8d8577}\px{c5b36f}\px{847749}\px{c3af76}\px{a8a5ab}\px{ffffff}\\[-9pt]\px{d6d5d8}\px{685c5a}\px{cfbc75}\px{d0bf79}\px{a49f9c}\px{9fa5c2}\px{a5a9c5}\px{9ba4c1}\px{93a0bd}\px{8c98b6}\px{8894b2}\px{686764}\px{d0be71}\px{ccb86e}\px{4d4146}\px{fffffe}\\[-9pt]\px{79747f}\px{b1a16e}\px{d0bd73}\px{9d907d}\px{a69398}\px{9ea2bf}\px{9aa2c0}\px{93a0bc}\px{8d9ab8}\px{8996b4}\px{8491ad}\px{9e948f}\px{666053}\px{afa062}\px{a79365}\px{c1bec2}\\[-9pt]\px{6c656e}\px{e8d284}\px{e8d47c}\px{7f849b}\px{b29587}\px{d19875}\px{9297b5}\px{8d9bb8}\px{958a8d}\px{b69e81}\px{d69d5a}\px{7f6465}\px{63677b}\px{e4d17a}\px{b7a366}\px{78737d}\\[-9pt]\px{443d49}\px{e9d47e}\px{dac776}\px{7b83a1}\px{8d95ad}\px{e5974c}\px{84788a}\px{a99c8c}\px{bf9567}\px{e89948}\px{9d694f}\px{686f8a}\px{6b748f}\px{d7c472}\px{c3ad68}\px{6b6170}\\[-9pt]\px{554c57}\px{e3cf7d}\px{d4c271}\px{63697e}\px{8692b0}\px{d08f54}\px{9a6456}\px{af7e5e}\px{7a666f}\px{7e6368}\px{6a718c}\px{7e8dae}\px{69728c}\px{cebc6e}\px{b29b60}\px{58505f}\\[-9pt]\px{564d5a}\px{ebda8e}\px{e0cd78}\px{888a8a}\px{8091b2}\px{a38783}\px{a75b47}\px{83666c}\px{808daf}\px{8492b3}\px{7f90b1}\px{7d8eb0}\px{605e62}\px{decc77}\px{bba567}\px{6a6570}\\[-9pt]\px{969199}\px{948464}\px{b7a56e}\px{b1a46d}\px{7782a1}\px{7f8dae}\px{876773}\px{7f5a6b}\px{83849f}\px{8592b3}\px{8392b2}\px{7885a1}\px{a09667}\px{d1c074}\px{5b4b46}\px{dad9db}\\[-9pt]\px{fefdfe}\px{574b4c}\px{d4c176}\px{a6945d}\px{c2b476}\px{7a849f}\px{808faf}\px{7f8dae}\px{818cac}\px{8b97b7}\px{7b86a2}\px{ab9e6b}\px{b09e65}\px{d2bc75}\px{675f69}\px{fdfdfd}\\[-9pt]\px{ffffff}\px{dad9db}\px{776653}\px{d3be74}\px{c4b26c}\px{c9b870}\px{7c7257}\px{797a7b}\px{8b8984}\px{948c72}\px{ccba75}\px{bcac6d}\px{d7bd72}\px{6c5c55}\px{cfcdd0}\px{ffffff}\\[-9pt]\px{ffffff}\px{fffefe}\px{88828c}\px{76624e}\px{cfb871}\px{cbb76e}\px{b7a567}\px{e5d280}\px{c6b56f}\px{d0bd71}\px{cfbc76}\px{c0a866}\px{57494a}\px{b5b1b8}\px{fefefe}\px{ffffff}\\[-9pt]\px{ffffff}\px{ffffff}\px{ffffff}\px{c2bfc4}\px{5d525b}\px{786451}\px{a18a5d}\px{d7c073}\px{b9a166}\px{8e7754}\px{67554d}\px{7d757e}\px{dbdbdd}\px{feffff}\px{ffffff}\px{ffffff}\\[-9pt]\px{ffffff}\px{ffffff}\px{ffffff}\px{ffffff}\px{f1f0f1}\px{d1cfd2}\px{928e95}\px{403746}\px{554d5a}\px{bab8bd}\px{bcbabf}\px{fffffe}\px{fffffe}\px{ffffff}\px{ffffff}\px{ffffff} |
|
\newcommand{\px}[1]{\color{#1}{\rule{5pt}{5pt}}}\px{fefefe}\px{fefefe}\px{fefefe}\px{fefefe}\px{fefefe}\px{fdf8c0}\px{e4bd6a}\px{cf8441}\px{be6639}\px{c26c2d}\px{dfb872}\px{fcf9e1}\px{fefefe}\px{fefefe}\px{fefefe}\px{fefefe}\\[-9pt]\px{fefefe}\px{fefefe}\px{fefefe}\px{fefef8}\px{d39a50}\px{b13e25}\px{a10302}\px{b13534}\px{bd6867}\px{a00201}\px{ad3131}\px{bf611f}\px{f8eaa8}\px{fefefe}\px{fefefe}\px{fefefe}\\[-9pt]\px{fefefe}\px{fefefe}\px{fefdee}\px{ce8136}\px{a20b04}\px{be7373}\px{a10909}\px{9b0c0d}\px{ab4647}\px{a00203}\px{be7879}\px{bd6666}\px{a81e04}\px{eed797}\px{fefefe}\px{fefefe}\\[-9pt]\px{fefefe}\px{fefefe}\px{f0d97d}\px{a00b07}\px{a20302}\px{a41f20}\px{a64f50}\px{466f71}\px{3f9699}\px{6f2e30}\px{ac3334}\px{a81b1a}\px{9f0303}\px{b0390a}\px{faf4d4}\px{fefefe}\\[-9pt]\px{fefefe}\px{faf3d0}\px{b23b18}\px{d29c9c}\px{ac3635}\px{9f0303}\px{536769}\px{7df3f7}\px{88f8fe}\px{58d2d5}\px{8e1616}\px{a10303}\px{af3d3c}\px{c57b7b}\px{dfaf62}\px{fefefe}\\[-9pt]\px{fefefe}\px{e8c988}\px{9e0302}\px{ad2c2c}\px{82484a}\px{499091}\px{79e8eb}\px{94d3ce}\px{938f77}\px{87ebed}\px{5abbbe}\px{4f6d70}\px{9c0b0a}\px{a10302}\px{ae2d05}\px{fefddf}\\[-9pt]\px{fefefe}\px{d1853b}\px{aa2526}\px{980e0f}\px{479fa0}\px{9ee5e2}\px{a8bfb7}\px{b78d77}\px{a29b91}\px{bca48e}\px{9ad0cc}\px{82d1cd}\px{6a5655}\px{a10d0e}\px{a51705}\px{f3e5ab}\\[-9pt]\px{fefefe}\px{c46d3d}\px{aa3e3e}\px{7b3132}\px{6cc279}\px{8ba178}\px{b48b7b}\px{b5b1ab}\px{b7e0db}\px{b9b5ac}\px{a69d8d}\px{84a368}\px{5d946a}\px{ad4444}\px{af4b4a}\px{e0bb64}\\[-9pt]\px{fefefe}\px{c16120}\px{a10a0a}\px{7b4243}\px{51a443}\px{7db06a}\px{b3bcac}\px{bcd4ca}\px{a9846d}\px{bdbeb5}\px{b3d0be}\px{5b9f2e}\px{469571}\px{a00303}\px{a00706}\px{e7cc91}\\[-9pt]\px{fefefe}\px{d28c51}\px{a00303}\px{901010}\px{4fa389}\px{347100}\px{b0c4a4}\px{bcac9d}\px{bb978c}\px{cbcdc2}\px{71a469}\px{307713}\px{656a6a}\px{a00303}\px{a41205}\px{f5eab1}\\[-9pt]\px{fefefe}\px{e5bc78}\px{aa3232}\px{9e0605}\px{843334}\px{3d9e91}\px{70a888}\px{cfdede}\px{ccd2d2}\px{c8dcd7}\px{519568}\px{4e867e}\px{940b0b}\px{b0403f}\px{b13b0c}\px{fefce5}\\[-9pt]\px{fefefe}\px{fefdd6}\px{b23c18}\px{ac4242}\px{a20302}\px{950b0c}\px{547879}\px{d1e8eb}\px{c9b5b7}\px{87c0c3}\px{7b2020}\px{a10303}\px{a40f10}\px{ac4b4c}\px{d39257}\px{fefefe}\\[-9pt]\px{fefefe}\px{fefefe}\px{d79d4f}\px{ab3d3b}\px{a32120}\px{a20302}\px{910e0e}\px{598d90}\px{68bbbe}\px{605556}\px{a20303}\px{9f0202}\px{ba6464}\px{aa3015}\px{f6edca}\px{fefefe}\\[-9pt]\px{fefefe}\px{fefefe}\px{fefeee}\px{c97c48}\px{a93c3c}\px{a93b3c}\px{a10706}\px{a00202}\px{a00302}\px{9f0202}\px{ab2929}\px{b05151}\px{a01806}\px{f2e29c}\px{fefefe}\px{fefefe}\\[-9pt]\px{fefefe}\px{fefefe}\px{fefefe}\px{fefce1}\px{cc7d3a}\px{ad3927}\px{ae5050}\px{ba6465}\px{b65656}\px{b24d4c}\px{ab3f3f}\px{bc641f}\px{f3e090}\px{fefefe}\px{fefefe}\px{fefefe}\\[-9pt]\px{fefefe}\px{fefefe}\px{fefefe}\px{fefefe}\px{fefefe}\px{f6eaa7}\px{d9a055}\px{b24404}\px{cb760b}\px{c67318}\px{e3c27b}\px{f9f4db}\px{fefefe}\px{fefefe}\px{fefefe}\px{fefefe} |
| 蒙娜丽莎 |
\newcommand{\px}[1]{\color{#1}{\rule{5pt}{5pt}}}\px{697a4e}\px{697b4c}\px{677748}\px{667748}\px{617344}\px{607446}\px{6a7746}\px{6a7d4f}\px{677a4c}\px{647746}\px{6a7947}\px{647546}\px{62754a}\px{667d50}\px{5f754e}\px{5c6846}\\[-9pt]\px{818b57}\px{808b56}\px{848d59}\px{818954}\px{838a54}\px{878d53}\px{827844}\px{6e643d}\px{5d5136}\px{72784c}\px{818b57}\px{818754}\px{848d5c}\px{868e5b}\px{858c56}\px{757c50}\\[-9pt]\px{909663}\px{979d66}\px{9b9e68}\px{9b9d65}\px{9a9d65}\px{827349}\px{bc9547}\px{ae873d}\px{5a3b1f}\px{211019}\px{6a6b49}\px{8f9762}\px{959c67}\px{9c9e67}\px{96985d}\px{85895a}\\[-9pt]\px{666b49}\px{73774d}\px{7a7c4e}\px{909364}\px{979862}\px{6a472f}\px{c79c4d}\px{bb9144}\px{8b642d}\px{2b171d}\px{2c2725}\px{606e4b}\px{7e8a5b}\px{a9a96a}\px{95965d}\px{767f5d}\\[-9pt]\px{49473a}\px{535740}\px{54583c}\px{525238}\px{4b4230}\px{573020}\px{c09449}\px{b18640}\px{926933}\px{25131b}\px{1a111a}\px{464d39}\px{4f6148}\px{6b754f}\px{626748}\px{626653}\\[-9pt]\px{403a2f}\px{454231}\px{504e39}\px{515540}\px{544e37}\px{3c1c1d}\px{75522f}\px{956d37}\px{50311e}\px{301b1d}\px{22171f}\px{4a523c}\px{48523b}\px{414938}\px{4e5746}\px{4f524c}\\[-9pt]\px{494037}\px{52513c}\px{665a38}\px{5b5038}\px{433929}\px{3b1e21}\px{684a2a}\px{a5823e}\px{a9853e}\px{643f1e}\px{3a231e}\px{322823}\px{62623d}\px{6f683c}\px{655e3f}\px{595042}\\[-9pt]\px{63412f}\px{6d4927}\px{81602a}\px{654722}\px{362121}\px{8f612d}\px{e7c264}\px{eac568}\px{e0b95b}\px{916428}\px{604127}\px{573822}\px{412f26}\px{766037}\px{7f6d42}\px{7a6a47}\\[-9pt]\px{623a30}\px{824f27}\px{83552c}\px{2e1d28}\px{382422}\px{856134}\px{a98849}\px{be9b54}\px{a88944}\px{694f2e}\px{382721}\px{251b21}\px{191324}\px{3a2631}\px{633834}\px{6e4c44}\\[-9pt]\px{5d4037}\px{855433}\px{6f4530}\px{2e2230}\px{33242a}\px{3a2929}\px{4d392b}\px{4b3827}\px{291e23}\px{1e1721}\px{3b2922}\px{482f21}\px{261b29}\px{2c2231}\px{5c3934}\px{64453e}\\[-9pt]\px{513d3b}\px{493734}\px{3a282e}\px{412a2b}\px{2d1e28}\px{2b1f28}\px{3c2b29}\px{322226}\px{211926}\px{171321}\px{211821}\px{210f1d}\px{1b0f21}\px{251e2f}\px{382d3b}\px{543c3c}\\[-9pt]\px{422f34}\px{351f2d}\px{57342b}\px{59372b}\px{462e28}\px{4b352c}\px{38262b}\px{1f1426}\px{171225}\px{121025}\px{130f23}\px{200d1f}\px{1a0d21}\px{221b2e}\px{2a2337}\px{4c3d44}\\[-9pt]\px{352433}\px{261a2f}\px{39212b}\px{492d2b}\px{966c38}\px{b88840}\px{b6853d}\px{7e572f}\px{472f28}\px{412a22}\px{3f2620}\px{2f1722}\px{1b1128}\px{221a2f}\px{21192f}\px{372836}\\[-9pt]\px{20162f}\px{1a0f27}\px{1a1026}\px{41272a}\px{9a6c34}\px{87572e}\px{7b4e2b}\px{8b582a}\px{67331e}\px{432019}\px{401d18}\px{33151a}\px{190b1c}\px{120c21}\px{21152a}\px{3e222a}\\[-9pt]\px{1b1029}\px{1b1026}\px{1c1025}\px{271424}\px{482621}\px{36191e}\px{341b1f}\px{26131e}\px{200f1e}\px{12091c}\px{090518}\px{0d071a}\px{080518}\px{1a0f22}\px{231225}\px{2a1829}\\[-9pt]\px{150c26}\px{160c25}\px{130a21}\px{1e0e22}\px{170d24}\px{1d0b1f}\px{1f0b1f}\px{11091e}\px{0c081d}\px{0d061b}\px{08061c}\px{060216}\px{060319}\px{080318}\px{100619}\px{22182d} |
| 戴珍珠耳环的少女 |
\newcommand{\px}[1]{\color{#1}{\rule{5pt}{5pt}}}\px{0e0f12}\px{0e1011}\px{0e0f12}\px{0e0e12}\px{0d0d12}\px{0d0c11}\px{0c0b11}\px{0c0b11}\px{0c0a11}\px{0c0b11}\px{0d0c0f}\px{0d0c0f}\px{0e0d11}\px{0e0e10}\px{0f0f10}\px{101010}\\[-9pt]\px{0f1112}\px{101112}\px{101214}\px{0f1014}\px{0d0d13}\px{0c0a12}\px{0c0a12}\px{0c0a12}\px{100e14}\px{3c382b}\px{302c24}\px{101011}\px{0f0e10}\px{101011}\px{101011}\px{0f1010}\\[-9pt]\px{0f1112}\px{101214}\px{101215}\px{0f1115}\px{0f1013}\px{0d0d12}\px{1a1a21}\px{373a42}\px{808183}\px{9f9779}\px{9b8e63}\px{5f573c}\px{111112}\px{0f0f12}\px{0f0f10}\px{0f0f10}\\[-9pt]\px{0f1012}\px{101215}\px{111316}\px{111315}\px{0f0f13}\px{202128}\px{868fa6}\px{8792b3}\px{6e7daa}\px{5d6a97}\px{4a4d58}\px{56503d}\px{2f2c24}\px{0f0f12}\px{0f0f12}\px{0f0f11}\\[-9pt]\px{0e1011}\px{121414}\px{111413}\px{111314}\px{101212}\px{857d78}\px{b6aeaa}\px{74778d}\px{495681}\px{323d61}\px{1f2640}\px{2d303b}\px{4f4834}\px{121114}\px{0f0f10}\px{0f0f10}\\[-9pt]\px{0e1011}\px{0f1111}\px{0e1012}\px{101212}\px{131313}\px{807164}\px{b7a18a}\px{947e67}\px{3d3739}\px{171d32}\px{161e36}\px{181f34}\px{62583d}\px{1d1d1b}\px{0f0e11}\px{0f0f0f}\\[-9pt]\px{0f1010}\px{101111}\px{101212}\px{0f0f10}\px{131313}\px{b19887}\px{a1866c}\px{a48d75}\px{614e41}\px{292527}\px{171d2e}\px{111523}\px{5d5538}\px{262525}\px{0f0f10}\px{0f0f10}\\[-9pt]\px{0f1010}\px{0f0f11}\px{111312}\px{0f0f0f}\px{111012}\px{7e695e}\px{836953}\px{a78c6d}\px{4b3a32}\px{352a25}\px{1d1b1a}\px{121213}\px{6a5f41}\px{535145}\px{111215}\px{0f0f0f}\\[-9pt]\px{101211}\px{0f1010}\px{101111}\px{101110}\px{101011}\px{54493f}\px{846454}\px{74614f}\px{5b4a3d}\px{453d35}\px{232321}\px{242422}\px{857751}\px{7e7864}\px{21242a}\px{101010}\\[-9pt]\px{0f1111}\px{0f1011}\px{0f1111}\px{0f0e12}\px{0f0f11}\px{141413}\px{2b2723}\px{49433b}\px{a09788}\px{888379}\px{65655f}\px{383731}\px{786c49}\px{81785b}\px{292a31}\px{101010}\\[-9pt]\px{0d0d11}\px{0d0c12}\px{0d0d11}\px{0e0e11}\px{0e0d12}\px{0e0d11}\px{0f0f11}\px{7f7b72}\px{a7915d}\px{494333}\px{1d1e1a}\px{1b1b19}\px{71674a}\px{7f7455}\px{595a56}\px{121313}\\[-9pt]\px{0d0c11}\px{0c0b11}\px{0d0d12}\px{0e0d12}\px{0d0c11}\px{0d0c11}\px{1f1d1d}\px{7b6a44}\px{957d44}\px{665937}\px{1f1f1a}\px{181816}\px{52514b}\px{7c7d72}\px{8e8d7a}\px{1a1b1e}\\[-9pt]\px{0d0c11}\px{0c0b10}\px{0d0c11}\px{0d0c11}\px{0c0b11}\px{0c0b10}\px{3c372d}\px{89754a}\px{816f45}\px{70603d}\px{302b21}\px{22211b}\px{2c2f34}\px{35373e}\px{111115}\px{131412}\\[-9pt]\px{0d0c12}\px{0c0b12}\px{0d0c11}\px{0c0b12}\px{0c0b12}\px{110e13}\px{786845}\px{886e41}\px{5c5039}\px{5a503a}\px{373227}\px{22211c}\px{23221c}\px{121115}\px{101013}\px{111110}\\[-9pt]\px{0d0c11}\px{0d0b12}\px{0d0d12}\px{0d0c12}\px{0d0c12}\px{483e2e}\px{907948}\px{594a31}\px{574a34}\px{584c32}\px{363125}\px{21201b}\px{28261e}\px{141416}\px{0e0e12}\px{101010}\\[-9pt]\px{0f0e11}\px{0e0e12}\px{0e0d12}\px{0c0b11}\px{161417}\px{7e6b48}\px{846d42}\px{493f2f}\px{554833}\px{564932}\px{2f2c22}\px{1c1c1a}\px{191917}\px{171716}\px{0f0e12}\px{0f0f0f} |
可以看到还是有点感觉的。
备注
为了方便地使用它,我让 Claude 写了一个简陋的 GUI。
把它和 pic2tex.py 放到一个目录下就可以运行。
运行截图: