javascript 将文本嵌入 PNG
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3335220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Embed text into PNG
提问by Cheery
I'm looking for a tool that'd let me embed json-formatted information inside a PNG -file.
我正在寻找一种工具,可以让我将 json 格式的信息嵌入到 PNG 文件中。
This far it's been quite quiet. Do I have to write it myself?
到此为止已经很安静了。我必须自己写吗?
I'd be especially interested of doing it with javascript. Into an image I extract from a canvas with toDataURL-method.
我对用 javascript 做这件事特别感兴趣。进入我使用toDataURL-method从画布中提取的图像。
回答by Wayne Werner
If you want to embed text you may want to look at this in particular, which comes from the PNGspecification. It seems a little on the complicated side.
如果您想嵌入文本,您可能需要特别查看它,它来自PNG规范。这似乎有点复杂。
The "easy" steganographicmethod looks a little more simple.
“简单”的隐写方法看起来更简单一些。
What may actually be better suited for your purpose is to create a javascript object that contains the image data and the JSON data - then just pass that object around wherever you need it.
实际上可能更适合您的目的是创建一个包含图像数据和 JSON 数据的 javascript 对象 - 然后将该对象传递到您需要的任何地方。
回答by the_e
I am completely unfamiliar with Python, however if you can access any of the prominent image processing libraries it is possible.
我完全不熟悉 Python,但是如果您可以访问任何著名的图像处理库,那是可能的。
Take a look herefor ImageMagick<->Python solutions.
看看这里的ImageMagick的< - > Python的解决方案。
Edit
编辑
You may wish to take a look at this blog postfor information regarding steganography (hiding information within an image) and an offshoot of the ImageMagick library. It uses C++ here but I'm sure you could figure out a way to incorporate the base processes in Python.
您可能希望查看此博客文章,了解有关隐写术(在图像中隐藏信息)和 ImageMagick 库的一个分支的信息。它在这里使用 C++,但我相信您可以找到一种将基本进程合并到 Python 中的方法。
回答by oldestlivingboy
Hmm, here's a partial libpng implementation in JS: http://www.xarg.org/download/pnglib.js.
嗯,这是 JS 中的部分 libpng 实现:http: //www.xarg.org/download/pnglib.js。
回答by tzot
Copying another answer of mine in another question:
在另一个问题中复制我的另一个答案:
Here's an old not too-fancy module I did for a friend once (Python 2.x code):
这是我曾经为朋友做过的一个不太花哨的旧模块(Python 2.x 代码):
the code
代码
from __future__ import division
import math, os, array, random
import itertools as it
import Image as I
import sys
def encode(txtfn, imgfn):
with open(txtfn, "rb") as ifp:
txtdata= ifp.read()
txtdata= txtdata.encode('zip')
img= I.open(imgfn).convert("RGB")
pixelcount= img.size[0]*img.size[1]
## sys.stderr.write("image %dx%d\n" % img.size)
factor= len(txtdata) / pixelcount
width= int(math.ceil(img.size[0]*factor**.5))
height= int(math.ceil(img.size[1]*factor**.5))
pixelcount= width * height
if pixelcount < len(txtdata): # just a sanity check
sys.stderr.write("phase 2, %d bytes in %d pixels?\n" % (len(txtdata), pixelcount))
sys.exit(1)
## sys.stderr.write("%d bytes in %d pixels (%dx%d)\n" % (len(txtdata), pixelcount, width, height))
img= img.resize( (width, height), I.ANTIALIAS)
txtarr= array.array('B')
txtarr.fromstring(txtdata)
txtarr.extend(random.randrange(256) for x in xrange(len(txtdata) - pixelcount))
newimg= img.copy()
newimg.putdata([
(
r & 0xf8 |(c & 0xe0)>>5,
g & 0xfc |(c & 0x18)>>3,
b & 0xf8 |(c & 0x07),
)
for (r, g, b), c in it.izip(img.getdata(), txtarr)])
newimg.save(os.path.splitext(imgfn)[0]+'.png', optimize=1, compression=9)
def decode(imgfn, txtfn):
img= I.open(imgfn)
with open(txtfn, 'wb') as ofp:
arrdata= array.array('B',
((r & 0x7) << 5 | (g & 0x3) << 3 | (b & 0x7)
for r, g, b in img.getdata())).tostring()
findata= arrdata.decode('zip')
ofp.write(findata)
if __name__ == "__main__":
if sys.argv[1] == 'e':
encode(sys.argv[2], sys.argv[3])
elif sys.argv[1] == 'd':
decode(sys.argv[2], sys.argv[3])
the algorithm
算法
It stores a byte of data per image pixel using: the 3 least-significant bits of the blue band, the 2 LSB of the green one and the 3 LSB of the red one.
它使用以下方式为每个图像像素存储一个字节的数据:蓝色波段的 3 个最低有效位、绿色波段的 2 LSB 和红色波段的 3 LSB。
encode function: An input text file is compressed by zlib, and the input image is resized (keeping proportions) to ensure that there are at least as many pixels as compressed bytes. A PNGimage with the same name as the input image (so don't use a ".png" filename as input if you leave the code as-is :) is saved containing the steganographic data.
encode 函数:输入文本文件由 zlib 压缩,并调整输入图像的大小(保持比例)以确保至少有与压缩字节一样多的像素。一个PNG具有相同的名称作为输入图像的图像(所以不要,如果你离开代码按:)保存含有隐写数据使用“png格式”文件名作为输入。
decode function: The previously stored zlib-compressed data are extracted from the input image, and saved uncompressed under the provided filename.
解码功能:先前存储的 zlib 压缩数据从输入图像中提取,并以提供的文件名未压缩保存。
I verified the old code still runs, so here's an example image containing steganographic data:
我验证了旧代码仍然运行,所以这是一个包含隐写数据的示例图像:


You'll notice that the noise added is barely visible.
您会注意到添加的噪音几乎不可见。
回答by user1983983
You can use the recently released JavaScript library steganography.js. Have a look at the showcase and the documentation for the basic usage.
The library makes use of a HTML canvasand embeds the information in the alpha channel of the image. Basically you just need to use steg.encode(message, image)and pass the JSON-data (as string) as message and the image as dataURL. To read this information from the image use steg.decode(image)and pass the image as dataURL again.
您可以使用最近发布的 JavaScript 库steganography.js。查看展示和文档以了解基本用法。
该库使用 HTMLcanvas并将信息嵌入图像的 alpha 通道中。基本上你只需要使用steg.encode(message, image)和传递 JSON 数据(作为字符串)作为消息和图像作为 dataURL。要从图像中读取此信息,steg.decode(image)请再次将图像作为 dataURL 传递。
After reading the information again you get the JSON-data as string so you will have to parse it to a JavaScript object again. So besides the parsing from/to string I hope it fits your requirements.
再次阅读信息后,您将获得 JSON 数据作为字符串,因此您必须再次将其解析为 JavaScript 对象。因此,除了从/到字符串的解析之外,我希望它符合您的要求。
回答by Blauharley
Why not just use this tool?
为什么不直接使用这个工具?
and here on github:
在 github 上:
https://github.com/blauharley/LoremImageCryptonator
https://github.com/blauharley/LoremImageCryptonator
It's a normal object that can be used for embedding text into each color-channel(red, green...).
它是一个普通对象,可用于将文本嵌入到每个颜色通道(红色、绿色...)中。
When embedding text into the alpha-channel there should not be as much noise as embedding text on other color-channels, so you should not see any difference before and after inserting text into an image.
将文本嵌入 alpha 通道时,噪音不应与在其他颜色通道上嵌入文本一样多,因此在将文本插入图像之前和之后,您不应看到任何差异。
回答by PleaseStand
Someone has already attempted to embed a Mario-like platformer gamein a PNG image. Using getImageDatais the key to reading out the data; the object that that method returns gives a one-dimensional array holding the individual RGBA values of each pixel.
有人已经尝试在 PNG 图像中嵌入类似马里奥的平台游戏。使用getImageData是读出数据的关键;该方法返回的对象给出了一个一维数组,其中包含每个像素的各个 RGBA 值。
Note that this does not "hide" the data within the area that the user sees, but you could probably use a CSS sprite like technique (or "crop" the image using multiple canvases) to show only the part of a combined image you want to.
请注意,这不会“隐藏”用户看到的区域内的数据,但您可能可以使用类似 CSS 精灵的技术(或使用多个画布“裁剪”图像)来仅显示您想要的组合图像的一部分到。

