Bug(バグ) #3195
Youichi Kimura さんが約12年前に更新
h3. Overview (現象) OpenPNE.yml にて @use_imagemagick@ を 1 または 2 に設定した場合、メンバーがアップロードした画像の表示に失敗する。 Apahceのエラーログには下記のようなエラーが出力される。 <pre> [Tue Sep 11 12:04:21 2012] [warn] [client 127.0.0.1] mod_fcgid: stderr: convert: unable to open image `/tmp/IGITF7GbcmB': No such file or directory @ error/blob.c/OpenBlob/2638.. convert: no decode delegate for this image format `/tmp/IGITF7GbcmB' @ error/constitute.c/ReadImage/544.. convert: no images defined `GIF:/home/upsilon/git/openpne3/sqlite/web/cache/img/gif/w120_h120/dc_3_f9d604c23c6725aad2f6dbfb8b2e9388c45b00ff_gif.gif' @ error/convert.c/ConvertImageCommand/3044., referer: http://sns.localhost:18080/sqlite/diary/4?comment_count=4 </pre> h3. Causes (原因) <pre><code class="diff"> diff --git a/lib/plugins/sfImageHandlerPlugin/lib/image/generator/sfImageGeneratorImageTransform.php b/lib/plugins/sfImageHandlerPlugin/lib/image/generator/sfImageGeneratorImageTransform.php index 4b442c9..b9fab74 100644 --- a/lib/plugins/sfImageHandlerPlugin/lib/image/generator/sfImageGeneratorImageTransform.php +++ b/lib/plugins/sfImageHandlerPlugin/lib/image/generator/sfImageGeneratorImageTransform.php @@ -64,7 +81,16 @@ abstract class sfImageGeneratorImageTransform extends sfImageGenerator if ($this->width && $this->height) { + $this->transform->crop($srcW, $srcH, $srcX, $srcY); + $tmpoutputfilename = tempnam(sys_get_temp_dir(), 'IGITF'); + $result = $this->transform->save($tmpoutputfilename); + if (PEAR::isError($result)) + { + throw new sfException($result->getMessage()); + } + $this->transform->load($tmpoutputfilename); $this->transform->fit($this->width, $this->height); + unlink($tmpoutputfilename); } } </code></pre> commit:4ff9ae5331ed12261ea80dec8c69b38eae1bacf8 に含まれる上記の修正において、画像の加工途中に生成された一時ファイルを load した後に unlink する処理が追加されている。GD を使用する場合には問題にならないが、ImageMagick を使用する場合は load メソッドを実行しても即座にファイルの内容がメモリ上にロードされるものではない(save メソッドが呼び出されるタイミングで convert コマンドが実行される)ため、save メソッドを実行する前に 変換元のファイルを削除してしまうと前述のようなエラーが発生してしまう。 h3. Way to fix (修正内容) sfImageGeneratorImage::doResize() に渡される $tmpfilename は最終的に 画像の一時ファイルは sfImageGenerator::__destruct() メソッドにて削除されるため、doResize() メソッドでの変換後の画像ファイルもこれと同じファイル名になっていることが望ましい。そのため、$tmpfilename で渡されたファイルを メソッドにて削除されるため、単に commit:4ff9ae5331ed12261ea80dec8c69b38eae1bacf8 で追加された unlink するのではなく、crop後の $tmpoutputfilename を $tmpfilename に rename して上書きするように修正を施す。 メソッドの行を除去するだけでよい