如果你儿时没有养过猫,却在四十岁时想与猫一起出现在泛黄的老照片里,你会怎么做?有人继续刷官网,有人打开代码编辑器。一个程序员用豆包API把自己和猫“塞”进了同一帧画面,还把整套流程打包成了可复用的Django应用,起名django-doubao,扔到了GitHub上。

这件事的起点,是一个童年的空洞。他小时候渴望一只猫,母亲却坚决不让。于是只能把脸贴在邻居家的玻璃上,看着那只虎斑猫在阳光里伸懒腰、打滚,胸腔里坠着一团说不清的空落。

打开网易新闻 查看精彩图片

四十年后,他终究有了自己的猫。但新的遗憾随即涌上来:他没办法和它一起长大。那些缺着门牙咧嘴笑的旧照片里,从来没有这只白胖的猫的影子。直到他想到一个讨巧的办法——用AI把两段时光粘合起来。

在字节跳动的豆包平台上,他上传自己褪色的童年照,再用图像融合功能把猫的脸合成进去。屏幕那头,原本毫无交集的男孩和猫忽然就在一张照片里玩耍了。接着他又生成视频:小男孩追着猫跑过花田,风撩起头发,时间仿佛被剪开又重新缝了一遍。每次创作,心就会轻轻漾一下——从沉寂的中央,一直荡到眼角和嘴角。

换成别人,故事到这里可能就结束了。但他是个程序员,脑子里蹦出一个念头:为什么不干脆自己做一个应用?于是他申请了豆包的API密钥,搭好一个Django项目,写了一个utils.py文件——不到三百行——就成了他自己的玩具工具箱。

他设计了两个视图:一个用来生成图像,另一个把图像转成视频。用户在前端上传原始照片,点下按钮,后台就开始调用豆包的生成接口。等图像一出来,紧接着就能把它扔进视频任务里,让静态的合影动起来。

当男孩和猫在屏幕上追逐时,某种旷日持久的空缺被轻轻补上了。他感觉,与其说是技术修复了照片,不如说是代码为迟到了四十年的陪伴搭了一座桥。

随后,他把整件事打包成一个标准的Python包——django-doubao。目录结构干净得一眼就能看明白:doubao/ 下面躺着 models.py,里面只定义了 ImageGeneration 和 VideoGeneration 两个模型,用来记录每次生成任务的状态和结果;views.py 里是 generate_image_view 和 generate_video_view 两个视图函数,一个对接图像生成,一个管理视频提交和轮询;urls.py 配置了带命名空间的路由,方便集成到其他项目里;最核心的调用逻辑缩在 utils.py 里,三个函数 generate_image、submit_video_task、poll_video_result 各自负责一张API的对接;templates 目录下则是独立的 Vue3 模板,不用依赖项目里的 base.html,直接就能渲染出交互界面。外加 migrations、tests 和 pyproject.toml,这个不到三百行的应用,居然还配了15个pytest测试用例,全部绿灯。

有人可能会说,直接打开豆包官网不就行了?图像合成、视频生成,网页端早就做得很流畅了。拖入图片、点击合成,几秒钟出结果,何必绕一大圈写代码、配路由、封装成包?

这种声音不无道理。对于只想偶尔玩一玩的人,官网提供的功能确实足够顺手。但站在这位程序员的视角,自建应用的意义远不止于“能跑”。他在代码里重新定义了童年和猫的互动方式——照片的尺寸、融合的强度、视频中花田的颜色,理论上每一处都可以按自己的记忆去微调。更重要的是,封装成包后,这套逻辑可以被任何人一键安装、二次开发,而不再是藏在浏览器缓存里的单次操作。

他本可以继续守在在线工具前,做一名普通用户。可当他打开编辑器时,选择的却是用代码构建一个“小世界”——一个男孩和猫终于能并肩奔跑、发呆、看枫叶一同飘落的世界。这个选择本身,已经回答了正方与反方的所有拉扯:对程序员而言,“能自己做”本身就是最强的动机。

安装它只需要四步。首先用 pip install django-doubao 把包装好,然后在项目的 INSTALLED_APPS 里加上 ‘doubao’,接着在设置里填上 DOUBAO_API_KEY 的字符串,最后在根路由里 include(‘doubao.urls’)。完成后,访问 /doubao/image/ 就能上传照片生成图像,转到 /doubao/video/ 又能把刚刚生成的静态图变成动态视频。整个过程流畅得就像一个现成的乐高零件,谁需要弥补旧照片里的空白,都可以直接拿来用。

如今这个包安安静静地躺在GitHub上,15条测试全绿。作者在README里写得简单:如果你也有类似的愿望——复活一张老照片,或者让一段记忆动起来——希望django-doubao能让你少走一些弯路。他没有大谈技术革新,