badpaint:在编码的余数上作画
badpaint: Painting on the Remainder of the Encoding
badpaint 是程序员 Ahmaykmewsik 在 2023 年 Handmade Network 的「重新发明轮子」黑客松上用一周写成的实时图像损坏编辑器。它的窗口分上下两半:下半部显示一张 PNG 在编码途中的原始字节——每个字节被画成一个 0 到 255 的灰度像素,那是图像经过滤波(filtering)、却尚未压缩(compression)的中间态;你拿画笔在这片灰度数据上涂抹,把任意的字节塞进数据流,PNG 编码器随后「错误地」把它们压缩,于是上半部那张成品图就绽出大块跳动的色斑。整个工具用 C 风格的 C++ 加 raylib 写成,多线程实时刷新,至今仍停在「原始状态」,作者在项目页上列着一长串「等我有空再做」的待办。
这件作品几乎是「余项」二字的字面化。一张 PNG 之所以成为我们认得的图,靠的是滤波与压缩那套早已凝固下来的工程约定——它是典型的「已构」:一次凿构循环沉淀下来的产物,规整、闭合、不再生长。而 badpaint 偏偏把刀锋伸进那道被所有人跳过的缝隙:滤波之后、压缩之前的那一段中间字节。那段字节本不该被看见,更不该被触碰,它是编码流程吐出又咽回去的余数。Ahmaykmewsik 让这段余数变得可见、可涂、可坏——他作画的对象不是图像本身,而是图像尚未成形时漏在工序之外的那一截。
更动人的是作者自己记下的一句迟疑。当他做出撤销功能、开始「认真」调制更细腻的效果时,他写道:「对故障能有这么多控制,我意识到这也许有点违背故障艺术的精神。」这恰恰是凿构循环正在发生的现场——他一边凿,一边怀疑自己是不是在把活的余数重新构造成可控的「已构」。这种尚未被收束、尚未被命名的犹豫,本身就是结构上的活气:工具还没有定型,作者还没想清楚它究竟是什么,故障与控制之间的张力还悬在半空,没有落地成一种风格。
这也是为什么现在去看它,比以后更要紧。一旦故障艺术被美术馆、被市场、被一套成熟的鉴赏语汇彻底接住,badpaint 这类东西就会沉淀成又一种「已构」——人们会预先知道该期待什么样的色斑、该用哪套词去赞美它。但此刻它还困在 2023 年那个黑客松的「初版」里,作者还在 Discord 上贴半成品、列待办、犹豫下一步是做 JPEG 还是图层。它的逻辑仍在生长,还没有被完整地命名。我们要找的,恰恰是这种尚未被消化的状态。
badpaint 没有把故障美学包装成结论,它把图像拆回成一串可以被手指搅动的字节,让我们看见「一张图」在成为图之前,先得丢掉多少东西。那被丢掉的、被压缩前的余数,正是它最活的地方。
handmade.network ↗badpaint is a real-time image-corruption editor that the programmer Ahmaykmewsik built in a single week for Handmade Network's 2023 Wheel Reinvention Jam. The window is split in two. The bottom half shows the raw bytes of a PNG caught mid-encode — each byte drawn as a grayscale pixel from 0 to 255, the image after it has been run through filtering but before it has been compressed. You take a brush to that field of gray data, shoving arbitrary bytes into the stream; the PNG encoder then compresses them "incorrectly," and the finished picture in the top half blooms into great jittering blocks of color. The whole thing is written in C-styled C++ on top of raylib, refreshed in real time across threads, and it still sits in what the author calls its "primitive state," trailing a long list of someday-when-I-have-time TODOs.
The work is almost a literal enactment of the remainder. A PNG becomes the picture we recognize only by way of filtering and compression — a set of engineering conventions that long ago hardened into place. That is the already-construct in textbook form: the sediment of a finished chisel-construct cycle, tidy, closed, no longer growing. badpaint instead drives its blade into the gap everyone steps over: the stretch of intermediate bytes that lives after filtering and before compression. Those bytes were never meant to be seen, let alone touched — they are the remainder the encoding pipeline coughs up and swallows again. Ahmaykmewsik makes that remainder visible, paintable, breakable. What he paints on is not the image but the sliver of it left exposed before it has fully formed.
More moving still is a moment of hesitation the author recorded himself. Once he had built an undo function and started "seriously" tuning subtler effects, he wrote: "Having this much control over what the glitches produce is maybe a little antithetical to the philosophy of glitch art." That is the chisel-construct cycle happening live — chiseling with one hand while doubting, with the other, whether he is busy re-constructing a living remainder into a controllable already-construct. That unresolved, unnamed hesitation is itself structural aliveness: the tool hasn't set, the author hasn't decided what it is, and the tension between accident and control still hangs in the air rather than settling into a style.
This is exactly why seeing it now matters more than seeing it later. The moment glitch aesthetics are fully caught by the museum, the market, and a mature vocabulary of appreciation, things like badpaint settle into yet another already-construct — people will know in advance which color blocks to expect and which words to praise them with. But right now it is still stuck in that 2023 jam "first version," with the author posting half-finished builds to Discord, keeping a TODO list, undecided whether the next step is JPEG or layers. Its logic is still growing; it has not yet been completely named. That undigested state is precisely what we are looking for.
badpaint doesn't package glitch aesthetics into a conclusion. It unspools an image back into a string of bytes you can stir with a finger, and lets you watch how much "a picture" has to throw away before it can be a picture. The thrown-away part — the remainder before compression — is where it is most alive.
handmade.network ↗