这一年以来,经常听说Claude在文学创作方面比ChatGPT更富有情感表现。而最近又听说Claude对于代码生成的能力也很强大。于是我便试了试。
先试了一下很基本的《黑客帝国》字母雨效果。我提出要求是:「编写一个HTML代码,来显示类似黑客帝国那样随机字符的绿色代码雨。」
Claude返回给我的代码是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Matrix Code Rain</title>
<style>
body {
margin: 0;
padding: 0;
background: black;
overflow: hidden;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%^&*()_+{}[]|;:,.<>?';
const fontSize = 16;
const columns = canvas.width / fontSize;
const drops = [];
for (let i = 0; i < columns; i++) {
drops[i] = 1;
}
function draw() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#0F0';
ctx.font = fontSize + 'px monospace';
for (let i = 0; i < drops.length; i++) {
const text = characters.charAt(Math.floor(Math.random() * characters.length));
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
}
setInterval(draw, 33);
</script>
</body>
</html>
将返回代码保存为一个本地HTML文件,在网页浏览器中打开,立即运行成功。
中间我又试了一下别的(全角字符)的。不过我想,生成黑客雨不能说明它智能呀,因为这种经典的效果肯定在网上能找到一大把现成的代码。
于是我就增加了一些要求,提出:「好,还是使用半角字符的黑客帝国字符雨,不过我要在此基础上增加以下两个功能。(1)根据我键盘按键上下左右方向键,页面能够刷新并且改变下雨的方向。(2)根据我按键盘的0~9数字键,可以切换字母雨的颜色:0:白色 1:红 2:橙 3:黄 4:绿 5:青 6蓝 7:紫 8:灰 9全部的字母雨变成彩虹色」
得到Claude返回结果中的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Enhanced Matrix Code Rain</title>
<style>
body {
margin: 0;
padding: 0;
background: black;
overflow: hidden;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%^&*()_+{}[]|;:,.<>?';
const fontSize = 16;
const columns = canvas.width / fontSize;
let drops = [];
let direction = 'down';
let rainColor = '#0F0';
let rainbow = false;
function initDrops() {
drops = [];
for (let i = 0; i < columns; i++) {
drops[i] = 1;
}
}
initDrops();
function draw() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = fontSize + 'px monospace';
for (let i = 0; i < drops.length; i++) {
const text = characters.charAt(Math.floor(Math.random() * characters.length));
if (rainbow) {
ctx.fillStyle = `hsl(${Math.random() * 360}, 100%, 50%)`;
} else {
ctx.fillStyle = rainColor;
}
let x, y;
switch (direction) {
case 'down':
x = i * fontSize;
y = drops[i] * fontSize;
break;
case 'up':
x = i * fontSize;
y = canvas.height - drops[i] * fontSize;
break;
case 'left':
x = canvas.width - drops[i] * fontSize;
y = i * fontSize;
break;
case 'right':
x = drops[i] * fontSize;
y = i * fontSize;
break;
}
ctx.fillText(text, x, y);
if ((direction === 'down' && y > canvas.height) ||
(direction === 'up' && y < 0) ||
(direction === 'left' && x < 0) ||
(direction === 'right' && x > canvas.width)) {
if (Math.random() > 0.975) {
drops[i] = 0;
}
}
drops[i]++;
}
}
document.addEventListener('keydown', (event) => {
switch (event.key) {
case 'ArrowUp':
direction = 'up';
break;
case 'ArrowDown':
direction = 'down';
break;
case 'ArrowLeft':
direction = 'left';
break;
case 'ArrowRight':
direction = 'right';
break;
case '0':
rainColor = '#FFFFFF';
rainbow = false;
break;
case '1':
rainColor = '#FF0000';
rainbow = false;
break;
case '2':
rainColor = '#FFA500';
rainbow = false;
break;
case '3':
rainColor = '#FFFF00';
rainbow = false;
break;
case '4':
rainColor = '#00FF00';
rainbow = false;
break;
case '5':
rainColor = '#00FFFF';
rainbow = false;
break;
case '6':
rainColor = '#0000FF';
rainbow = false;
break;
case '7':
rainColor = '#800080';
rainbow = false;
break;
case '8':
rainColor = '#808080';
rainbow = false;
break;
case '9':
rainbow = true;
break;
}
initDrops();
});
setInterval(draw, 33);
</script>
</body>
</html>
也是保存为HTML网页文件后,离线运行一次成功!就是本文最上方的截图了。
Claude真不错呀。下次试试看更复杂的。
是我呀。
Claude应该是我接触的第一个长文本分析语言模型(毕竟是免费的www)。记得我寒假做阅读任务的时候,把将近十几kb的文本喂给claude,它一下就概括出来了,我都震惊了 (* ̄3 ̄)╭
不过要写代码的话,依我的一点经验,github copilot最好用(毕竟是专业的),其次是chatgpt4o和Gemini(这俩货日常文本对话也不错)
不得不感叹,现在AI真是方便啊,我博客上的技术类文章的勘误都让chatgpt帮我
啊,你好。你说你把寒假作业喂给AI……呃,你们现在派发作业都用电子化的了吗?
我现在碰到的问题是:我手边很很多年表、史料、古文书,不少也可以是网上下载的。但大多都是扫描件(图片)而非文本。所以第一步OCR就成了问题。而我读的书是日文的,对于竖排日文的扫描件,目前我还没找到很好用的方式来进行OCR。所以目前我尚未能打通大部分实体书/扫描图像与AI之间的那个「壁垒」。
要是能把这些实体书或其扫描件,能用OCR的方式转换入AI,那或许AI能辅助我发现新的事实或价值观。
另外,这是我最近要求ClaudeAI用SVG图像(一种矢量图,可以用代码来描述图片)来表现日本地图、日本江户时代港口的试作图。
https://pbs.twimg.com/media/GS6ZZ-nasAAXChl?format=jpg&name=medium
嗯,虽然地点信息、位置关系都正确,但是地图形状有点……可爱。
好巧,我寒假作业也是把实体文章拍成图片识别(iPhone有个类似ocr的识别图片文字功能)的
说回正题,对于竖排文字,我想可否用某种AI的ocr呢?基于神经网络经过深度学习训练的OCR模型,效果通常会比传统的仅使用轮廓识别的OCR要好…吧?(或者有专门识别竖排日语的模型)(以上仅个人猜测)
(不过我以前见过,好像古代日语几乎全是汉字而没有假名吧?这样反而AI误差可能比较大)
不过这种技术类问题去看看国外某些开源社区论坛可能会有收获吧(比如github,huggingFace啥的)
对了,我看这篇识别竖排文字解决方案的文章挺有趣的(虽说需要点技术www) https://stackoverflow.com/questions/76074230/read-vertical-text-with-google-cloud-ocr
最后挺佩服博主的,居然每天都写文章
哦?你也是拍了再OCR的?你处理的对象是英文还是中文?识别正确率多少?
我觉得印刷体的英文可能比较容易准确识别。顺便一说我没有找专业OCR软件,只是用MacOS自带的OCR功能。
我之前也试过日本国立国会图书馆提供的OCR程序。
https://lab.ndl.go.jp/news/2023/2023-07-12/
我记得是用命令行操作的,效果嘛……也就这样了,我没仔细对比。因为如果每一页识别出的文字,还需要我花费30秒以上时间去看,那我还不如直接自己阅读……
日文文章有个特点是,不仅是竖着一行一行的,而且还有许多单词,写作者怕读者不认识,而在单词右侧注音,所以就增加了程序识别和判断到底哪里是文字列的难度了。
(注:因为与汉语中一个汉字几乎只有一个音不同,日文里有相当大量的词汇,其发音仅在这两个字构成该组合时才会发这个音。而且同一个单词还会有因为时代/流派不同,会有不同的发音。比如「茶道」这个词就根据茶道流派不同,它发音是不同的……)
关于博客写作嘛,最近起意,尝试连续更新,因为看了一本书,鼓励人们在输入/输出上花的时间要达到输入3:输出7,才能达到最有效的学习。
《一箩筐建议的《OUTPUT》》
http://wildgun.net/2024/06/bookreview_9784801400559/
不过访问量(PageView)嘛,没什么起色。
我ocr的是纯正的英文印刷体,所以准确率可以高达98%左右吧。不过排版是一大问题,毕竟每行都会换行,ocr就大概率把一句话拆成好几行了。
我一般用有道ocr,我用有道试了一下垂直排版的日文(节选自某小说)
原文:https://loneapex.cn/extra-js/pic/before.jpg
ocr结果(以图片形式识别):https://loneapex.cn/extra-js/pic/after.jpg
(它居然可以把竖排文字转成水平的文字哎)
当然也可以试试谷歌Cloud Vision和Tesseract(毕竟是开源的,数据库应该积累的挺大了)。
至于apple给的ocr嘛…只能说比微信搞的那个ocr误差还大
对于日语的单词注音嘛…如果罗马音的话还好说,但大多数好像是用假名注音吧(;′⌒`),一般没办法了
(不过用python和ocr api接口写一个ocr程序,倒是可以实现根据字符大小选择性的识别文字)
啊,说起博客嘛,我写文章只是作为一个自娱自乐的爱好罢了,对访问量倒是并不那么在意,哈哈
使用了一下Google的DocumentAI(好像也是一个OCR工具),提交PDF后屡次失败……
给Claude也用了一下(上传了PDF扫描件),它概括是概括了,但是似乎只愿意概括前几页的内容……
总之效果都是不太理想。