如何使用 php 将数据存储在图像中?
How to store data in an image with php?
我曾尝试使用 imagick 库创建如下两个函数:
function storeCoordinatesImage($img_path, $coordinates){
$im = new imagick($img_path);
$im->setImageProperty("coords", $coordinates);
$im->writeImage($img_path);
}
function getCoordinatesImage($img_path){
$im = new imagick($img_path);
return $im->getImageProperty("coords");
}
如果我运行:
if(!storeCoordinatesImage("I.jpg", "hi")) echo "fal";
echo getCoordinatesImage("I.jpg");
没有返回任何内容。
但是如果我运行:
$im = new imagick($img_path);
$im->setImageProperty("coords", "hello");
echo $im->getImageProperty("coords");
它returns "hello".
所以写入图像一定有问题?虽然 none 个函数返回 false
。 (即他们都在工作)
您似乎无法为 jpeg 保留该数据:https://github.com/ImageMagick/ImageMagick/issues/55#issuecomment-157114261
也许试试 png?
正如本所说,这是不可能的。相反,您可以添加 "comment":
function storeCommentImage($img_path, $coordinates){
$im = new imagick($img_path);
$im->commentImage($coordinates);
return $im->writeImage($img_path);
}
function getCommentImage($img_path){
$im = new imagick($img_path);
return $im->getImageProperty("comment");
}
使用图像的配置文件负载来存储任意数据。尽管存储在图像评论(即 JPG_COM
)标签中的 JSON 有效负载似乎是快速简单的,但针对此提议存在几种竞争技术。最受欢迎的是 exif, but I would recommend xmp.
可扩展元数据平台
在我看来,xmp
似乎设计过度,但确实提供了一个平台来确保所有供应商专有信息通过 XML 命名空间分开。
Wikipedia 有 great overview, and Adobe's white papers (pdf) 很好地概述了供应商要实施的 "does-n-don'ts"。
ImageMagick 不处理 read/write 配置文件有效负载之外的任何内容,因此您将负责实施 XML 管理器。
例如...
// A minimal XMP tempalte
$XMP_BASE='<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMPTk 2.8">'
.'<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"></rdf:RDF>'
.'</x:xmpmeta>';
$xmp = new DOMDocument();
$xmp->loadXML($XMP_BASE);
// Create a <rdf:Descriptiom> & <Coords> DOM element.
foreach($xmp->getElementsByTagName('RDF') as $node) {
$coords = $xmp->createElement('Coords', 'hello');
$description = $xmp->createElement('rdf:Description');
$description->setAttribute('about', '');
$description->appendChild($coords);
$node->appendChild($description);
}
$img = new Imagick('rose:');
// Write profile to image.
$img->setImageProfile('xmp', $xmp->saveXML());
$img->writeImage('output.jpg');
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$img2 = new Imagick('output.jpg');
$xmp2 = new DOMDocument();
// Read profile from image.
$xmp2->loadXML($img2->getImageProfile('xmp'));
// Grab `Coords' value
foreach($xmp2->getElementsByTagName('Coords') as $coords) {
print $coords->textContent . PHP_EOL;
}
//=> "hello"
并且您可以使用 identify
实用程序进行验证。
identify -verbose output.jpg | grep Coords
#=> Coords: hello
当然,如果图像已经包含 XMP 配置文件,并且您不希望覆盖现有数据。
我曾尝试使用 imagick 库创建如下两个函数:
function storeCoordinatesImage($img_path, $coordinates){
$im = new imagick($img_path);
$im->setImageProperty("coords", $coordinates);
$im->writeImage($img_path);
}
function getCoordinatesImage($img_path){
$im = new imagick($img_path);
return $im->getImageProperty("coords");
}
如果我运行:
if(!storeCoordinatesImage("I.jpg", "hi")) echo "fal";
echo getCoordinatesImage("I.jpg");
没有返回任何内容。
但是如果我运行:
$im = new imagick($img_path);
$im->setImageProperty("coords", "hello");
echo $im->getImageProperty("coords");
它returns "hello".
所以写入图像一定有问题?虽然 none 个函数返回 false
。 (即他们都在工作)
您似乎无法为 jpeg 保留该数据:https://github.com/ImageMagick/ImageMagick/issues/55#issuecomment-157114261
也许试试 png?
正如本所说,这是不可能的。相反,您可以添加 "comment":
function storeCommentImage($img_path, $coordinates){
$im = new imagick($img_path);
$im->commentImage($coordinates);
return $im->writeImage($img_path);
}
function getCommentImage($img_path){
$im = new imagick($img_path);
return $im->getImageProperty("comment");
}
使用图像的配置文件负载来存储任意数据。尽管存储在图像评论(即 JPG_COM
)标签中的 JSON 有效负载似乎是快速简单的,但针对此提议存在几种竞争技术。最受欢迎的是 exif, but I would recommend xmp.
可扩展元数据平台
在我看来,xmp
似乎设计过度,但确实提供了一个平台来确保所有供应商专有信息通过 XML 命名空间分开。
Wikipedia 有 great overview, and Adobe's white papers (pdf) 很好地概述了供应商要实施的 "does-n-don'ts"。
ImageMagick 不处理 read/write 配置文件有效负载之外的任何内容,因此您将负责实施 XML 管理器。
例如...
// A minimal XMP tempalte
$XMP_BASE='<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMPTk 2.8">'
.'<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"></rdf:RDF>'
.'</x:xmpmeta>';
$xmp = new DOMDocument();
$xmp->loadXML($XMP_BASE);
// Create a <rdf:Descriptiom> & <Coords> DOM element.
foreach($xmp->getElementsByTagName('RDF') as $node) {
$coords = $xmp->createElement('Coords', 'hello');
$description = $xmp->createElement('rdf:Description');
$description->setAttribute('about', '');
$description->appendChild($coords);
$node->appendChild($description);
}
$img = new Imagick('rose:');
// Write profile to image.
$img->setImageProfile('xmp', $xmp->saveXML());
$img->writeImage('output.jpg');
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$img2 = new Imagick('output.jpg');
$xmp2 = new DOMDocument();
// Read profile from image.
$xmp2->loadXML($img2->getImageProfile('xmp'));
// Grab `Coords' value
foreach($xmp2->getElementsByTagName('Coords') as $coords) {
print $coords->textContent . PHP_EOL;
}
//=> "hello"
并且您可以使用 identify
实用程序进行验证。
identify -verbose output.jpg | grep Coords
#=> Coords: hello
当然,如果图像已经包含 XMP 配置文件,并且您不希望覆盖现有数据。