你也想要漂亮的代码截图吗?

  • 楔子

想来很多人对这种风格的代码截图都很熟悉了:

vscode里有不少插件可以直接生成,比如我在用的CodeSnap,也有一些公开免费的网站,比如:carbon,甚至于carbon网站可以直接通过URL传递代码内容和截图风格的参数。

  • 正文

这种代码截图排版不乱、带语法高亮,非常适合代码传播和“抄”代码。我在搭建微信机器人后,实际体验中遇到的一个困扰,就是我在提问代码的时候,排版显得非常乱,于是我想到这个代码截图,试图通过程序的方式生成类似的图片。

最开始是找到了别人借助carbon网站做的api接口Carbon-APIcarbon-api。优点自不必说,排版精美、语法高亮支持性好、使用方便,唯一的缺点就是需要良好的网络支持。虽然官网没有被墙,但是由于我的小鸡宝网络不佳,实际使用中时不时会生成失败。

所以我开始寻找本地生成的方案,就是各种pygments做语法高亮+图片工具。过程就不再赘述了,虽然效果不如人家专业的精美,不过总算差强人意。最后把使用code2img代码给大家分享一下:

code2img.py
import pygments
from pygments.styles import get_style_by_name
from pygments.formatters import ImageFormatter
from pygments.lexers import get_lexer_for_filename,get_lexer_by_name
from PIL import Image, ImageDraw, ImageFilter, ImageEnhance
import io,os

def add_shadow_and_gradient(image_data):
    def add_gradient(size):
        gradient = Image.new('RGBA', size, color=0)
        draw = ImageDraw.Draw(gradient)

        start = (253, 46, 216)
        end = (23, 214, 255)
        deltas = [(b - a) / gradient.width / 2 for a, b in zip(start, end)]
        for i, color in enumerate(range(gradient.width * 2)):
            color = [round(s + d * i) for s,d in zip(start, deltas)]
            draw.line([(i, 0), (0, i)], tuple(color), width=1)
        return gradient
    image = Image.open(io.BytesIO(image_data))
    image = ImageEnhance.Color(image).enhance(2)
    pad_x, pad_y, offset_x, offset_y = 30, 30, 8, 8
    width, height = image.size

    bottom_canvas = add_gradient((width+pad_x, height+pad_y))
    shadow = Image.new('RGBA', (width, height), (20, 20, 20, 255))
    bottom_canvas.paste(shadow, (pad_x//2+offset_x,pad_y//2+offset_y))
    bottom_canvas = bottom_canvas.filter(ImageFilter.GaussianBlur(6))
    bottom_canvas.paste(image, (pad_x//2,pad_y//2))
    return bottom_canvas

def code2img(code_snippets, language):
    try:
        lexer = get_lexer_by_name(language)
    except:
        lexer = get_lexer_by_name("python")
    style = get_style_by_name('material')
    formatter = ImageFormatter(
        font_name = 'YaHei Consolas Hybrid',  # 一个对中英文混合代码字体比较友好的字体
        font_size = 30,
        style = style,
        line_pad = 10,
        line_number_bold = True,
        line_number_italic = True,
        line_number_bg = style.background_color,
        image_pad = 20,
        full = True
    )
    result = pygments.highlight(code_snippets, lexer, formatter)
    result = add_shadow_and_gradient(result)
    outname = os.getcwd() + '\\assets\\code-snippets.png'
    with open(outname, 'wb') as f:
        if isinstance(result, Image.Image):
            result.save(f)
        else:
            f.write(result)
9 Likes

https://www.codecopy.cn/search
代码传播

1 Like

人工智能软件分享


Create beautiful images of your code (ray.so) 我在用这个

1 Like

这是鱼皮做的那个吗?

26 Likes

是的

实用

就是不会自动换行,都超出了

:joy:才发现,我一般会控制一行代码的长度,没注意过

挺好的

好的谢谢

[已删除]

codesnap在帖子里提到了哦,代码实现主要是方便微信机器人给我发截图

不错,实用

不错,抽时间封装下可以自用

能有行号就好了