将文本块插入PNG图像

26

我正在寻找一个简单的命令行工具(在Linux上)来将文本块(例如版权声明)插入到png文件中,从而生成一个新的png文件:

> png-insert-text-chunk "here's my text chunk" < in.png > out.png

注意:在“插入文本块”的意义上,我并不是指“在图像上绘制一些文本”。我的意思是:将文本作为一个块插入到PNG文件中,在技术上的意义上。例如,这可以用于插入未显示在实际图像上的版权信息。


下次请尝试将类似的问题提交到unix.stackexchange.com,因为这与编程无关。 - Mr. Shickadance
1
@mr 我不明白为什么这个问题比这个或者这个与编程无关。如果我想要用Bash编写一个CGI脚本,将文本块插入到一组图像中,那么我就需要上面的命令,这听起来像是一个程序。 - gcbenison
他特别要求在Linux上使用命令行工具。我只是想指出unix.stackexchange.com的存在。 - Mr. Shickadance
使用php(命令行): http://stackoverflow.com/questions/8842387/php-add-itxt-comment-to-a-png-image/8856458#8856458 - leonbloy
@leonbloy 很棒,它有效了... 我可以继续寻找一个更轻量级的解决方案,而不需要启动一个php进程 - gcbenison
7个回答

19

使用ImageMagick的convert命令和-set选项:

convert IN.png \
        -set 'Copyright' 'CC-BY-SA 4.0' \
        -set 'Title' 'A wonderful day' \
        -set comment 'Photo taken while running' \
        OUT.png

-set选项用于设置元数据元素。在PNG的情况下,这些元素通常被放置在tEXt块中。


3
相反,要去除图像的属性,请使用+set "property" - sphakka
1
您可以使用 identify -verbose OUT.png(也是 ImageMagick 的一部分)提取属性。 - RobM

15

我已经搜索了各种工具来实现这个功能,但仍未找到真正符合我的需求的工具。所以我决定自己动手,事实证明这并不太难。实用程序png-text-dump显示PNG图像中的所有文本块,它仅依赖于libpng。实用程序png-text-append在PNG图像中插入文本块,它仅依赖于标准的C库 - 我最初尝试使用libpng实现此操作,但实际上发现仅使用PNG规范从头开始更容易。


谢谢你完成这项工作!我正在尝试将自己的元数据嵌入PNG中,并发现tEXt块是实现它的方法,但我没有看到任何支持它的工具。我将使用你的实用程序! - stephenmm
就此而言,“pngtools”包中的“pnginfo”具有显示png文件中文本块的能力。显然不同于添加自己的(感谢您提供的代码!),但有时对于快速处理一些东西很有用。 - arcticmac
我认为在png-text-append的第79行应该是: char name[5] = {'\0'}; // 4个字符和一个空终止符 参考: https://dev59.com/ZHDXa4cB1Zd3GeqP7gQa - Adam
@arcticmac,我的pnginfo(v0.4-r2)似乎找不到通过convert -set添加的任何额外(tEXt)字段...相反,exiftool(v10.25)可以做到! - sphakka
@sphakka 是的,如果我没记错,在 pnginfo 中存在一个错误,它只读取图像数据之前出现的文本块,而 convert 则在之后添加它们或类似的操作。了解 exiftool 的信息也很有用。 - arcticmac

6

这可以用Python pypng模块实现。以下是Python3示例代码:

import png

TEXT_CHUNK_FLAG = b'tEXt'


def generate_chunk_tuple(type_flag, content):
    return tuple([type_flag, content])


def generate_text_chunk_tuple(str_info):
    type_flag = TEXT_CHUNK_FLAG
    return generate_chunk_tuple(type_flag, bytes(str_info, 'utf-8'))


def insert_text_chunk(target, text, index=1):
    if index < 0:
        raise Exception('The index value {} less than 0!'.format(index))

    reader = png.Reader(filename=target)
    chunks = reader.chunks()
    chunk_list = list(chunks)
    print(chunk_list[0])
    print(chunk_list[1])
    print(chunk_list[2])
    chunk_item = generate_text_chunk_tuple(text)
    chunk_list.insert(index, chunk_item)

    with open(target, 'wb') as dst_file:
        png.write_chunks(dst_file, chunk_list)


def _insert_text_chunk_to_png_test():
    src = r'E:\temp\png\register_05.png'
    insert_text_chunk(src, 'just for test!')


if __name__ == '__main__':
    _insert_text_chunk_to_png_test()

这是一个非常有用的例子。我在pypng文档中没有看到这个概念...也许你可以将它提交给项目文档。 - michael_teter
好的想法,已经提交了一个问题:https://github.com/drj11/pypng/issues/85。 - cfh008
使用最新版Python时,我在write_chunk()中遇到了TypeError。解决方法是确保type_flag被发送为bytes而不是str:type_flag = bytes(TEXT_CHUNK_FLAG, 'utf-8') - michael_teter

5

注意:此回答是对最初版本的问题的回应,当时问题不清楚文本是否必须写在图像上,还是必须将文本嵌入到图像二进制文件中作为元数据。此回答假设前者。但是问题已经被编辑以澄清它意味着后者。为了防止有人寻找前者的解决方案,保留此回答。


convert -draw "text 20,20 'hello, world'" input.png output.png

上面例子中的20,20是我想要放置文本的坐标。
你需要使用imagemagick软件包来获取此命令。
在Ubuntu或Debian上,可以使用以下命令进行安装:apt-get install imagemagick
这里是一个稍微复杂一些的命令用法:
convert -font Helvetica -pointsize 20 -draw "text 20,20 'hello, world'" input.png output.png

2
我正在寻找一个能够插入PNG“文本块”的命令,即在文件中嵌入注释。但这是在图像上绘制文本的酷方法;我不知道convert可以做到这一点。 - gcbenison

0

补充@susam-pal的评论,要更改颜色,请使用选项

-fill color

此选项接受颜色名称、十六进制颜色或数字RGB、RGBA、HSL、HSLA、CMYK或CMYKA规范。有关正确指定颜色参数的说明,请参见颜色名称。

将颜色规范括在引号中,以防止“#”或括号被您的shell解释。

例如:

-fill blue

-fill "#ddddff"

-fill "rgb(255,255,255)"


链接获取


0

1
我稍微研究了一下pngcrush,它可以做到这一点;我的唯一问题是我似乎无法让它保持其他块不变。此外,我还没有能够让它简单地打印出png文件中现有文本块的内容。 - gcbenison

0
你可以在Python中使用pypng库。
#!/bin/python3

import png

reader = png.Reader(filename='input.png')
chunks = list(reader.chunks())

chunk_field = (b"tEXt", b"Profile\x00Profile Content Here")
chunks.insert(1, chunk_field)

file = open('output.png', 'wb')
png.write_chunks(file, chunks)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接