0

PostgreSQLから、画像ファイルをImagickオブジェクトに読み込もうとしています。そして、同じファイルを別のbyteaフィールドに書き直そうとしています。目的は、PHPとImagickで使用される文字列の処理と変換を完全に理解することです。

これはPostgreSQL9にあるため、ネイティブのbytea_outputは16進数です。私は、PHPで処理するためにbytea_outputをエスケープするように変更するためのメモに従っています。

最終的に、目的はこのファイルをImageMagickでサポートされている形式のいずれかに変換することです。

物事は十分に始まります!エスケープを解除すると、$imagestringはディスク上のファイルの長さになります。ここまでは順調ですね。その後まもなく物事は制御不能になります...

同じ長さのファイルをDBに再構成する、書き戻す文字列が見つかりません。

ここで何が問題に見えますか?

// 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 などの画像処理プログラムで同じことを試してみてください。Web で見つかった PNG を開き、別のファイル名で PNG として保存すると、同じ画像を表す 2 つの異なるファイルが得られます。

それが、さまざまなデータサイズを取得している理由だと思います。

于 2011-11-05T16:57:30.923 に答える