0

从 PostgreSQL 中,我试图将图像文件读入 Imagick 对象 - 并简单地将相同的文件重新写入另一个 bytea 字段。目标是充分理解 PHP 和 Imagick 中使用的字符串处理和转换。

这是在 PostgreSQL 9 上,所以本机 bytea_output 是十六进制;我一直在关注将 bytea_output 更改为转义以供 PHP 处理的注释。

最终,目标是将此文件转换为 ImageMagick 支持的任何格式。

事情开始得很好!取消转义后,$imagestring 就是磁盘上文件的长度。到现在为止还挺好。事情很快就失控了……

我找不到任何要写回的字符串,它将以相同的长度将文件重新构成回数据库。

这里看起来有什么问题?

// an entire image file is stored in the bytea col: bfile

$query = "SET bytea_output = 'escape'";
$result = spi_exec($query);

# Run the query and get the $result object.
$result = spi_exec($query);

# Fetch the row from the $result.
$row = spi_fetch_row($result);
$content = $row['bfile'];

// pg_unescape it to make it usable?
$unescaped   = pg_unescape_bytea($content);

// Image is read into imagestring
$imagestring = substr($unescaped,12); // remove Mac file header?
$length_image = strlen($imagestring); // 330,494 (EXACTLY length on disk)

// Create Imagick object
$im = new Imagick();

// Convert image into Imagick
$im->readimageblob($imagestring);

// Imagick::getImageSize is deprecated. use Imagick::getImageLength
// - here things get weird....
$image_in_length = $im->getImageLength(); // 330,897

// =============  DO WORK HERE  ====================================
/* Set format to pdf, or png, or... */
// THIS IS THE OBJECTIVE, of course!
// $im->setImageFormat( 'pdf' );
// =================================================================

// FOR THE TIME BEING, would like to simply re-write the same file
// Output the image
$output = $im->getimageblob(); 

//IS THIS RIGHT? ouput length is shorter?
$length_output = strlen($output); // 39,654

$escaped = pg_escape_bytea($output);
$length_escaped = strlen($escaped); // 182,720

// FINALLY: Re-concatenate the strings, and write back to blobtest:destfile:
// ALL of these produce the same result:
$query = "UPDATE blobtest SET destfile = '".$escaped."' WHERE pkey = '" .$args[0]. "'";
$result = spi_exec($query);

$length = getImageLength($image);
//return $inputtype;
$query = "SET bytea_output = 'hex'";
$result = spi_exec($query);

return $length;
4

1 回答 1

0

我认为 ImageMagick 不会记住它读取的确切图像数据——它会在运行时将其转换readImageBlob()为其内部格式,并在运行时将其转换为输出格式getImageBlob()

即使它是相同的格式——例如 PNG 输入和 PNG 输出——同样的图像可以以数百种方式保存——例如取决于压缩设置等。对于有损格式,如 JPG,你甚至不会得到相同的图像 - 只是它的近似值。

在任何图像处理程序中尝试相同的方法,例如 Gimp——打开在网上找到的一些 PNG,另存为 PNG 到另一个文件名——你会得到两个不同的文件代表同一个图像。

我认为这就是您获得不同数据大小的原因。

于 2011-11-05T16:57:30.923 回答