前置き
- Imagick、S3ともに知識が浅いです。参考程度にお願いします。
前提
- CentOS6.7(ローカルの開発環境なのでEC2じゃないです)
- Imagick, フォント系モジュールはインストール済み
- PDFの1枚目をJPEGに変換してサムネイルとしたい
始めの構想
ImagickでPDFの1ページ目をJPEGに変換し、S3に直接保存
こちらは、エラーが多発しなかなか実装できませんでした。
エラー文を見る限り、ファイルの実体が無いとアップロードできないようにうかがえました。表示するときだけ、JPEGにして表示する(実は試していない)
最終的な構想
ImagickでPDFの1ページ目をJPEGに変換し、自身のサーバー内に一次保存。
一次保存したファイルをS3へアップロードして、サーバー内のファイルを削除。
準備
- Imagickのインストール
- AWS SDK for PHPをCakePHP内のPluginディレクトリに入れておく(参照できればどこでもよし)
- PDFで使用されるであろうFont群もダウンロードしておく( imagick pdf とかでググってると、ここら辺たくさん出てくる)
コード
HogeController.php
<?php
/**
* HogeController
* ほげほげするコントローラー
**/
Class HogeController extends AppController {
public $components = ['Amazon'];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* 資料のサムネイルを作成する
* @param string $fileName 元ファイルのパス
* @return void
* */
private function _createThumnail($fileName){
$name = PREFIX_DOCUMENT.pathinfo($fileName, PATHINFO_FILENAME).".jpg"; //サムネイルのファイル名
$thumbname = PATH_TMP_IMG_DIR.DS.$name; //サムネイルの一次保存先
/* サムネイルの作成 */
$thumbImg = new Imagick(); // 画像の読み込み
$thumbImg->readImage(AWS_S3_HOSTNAME.AWS_S3_BUCKET."/xxxx/".$fileName); // 元ファイルのパス
$thumbImg->setImageIndex(0); // 1ページ目を指定
// $thumbImg->resizeImage(210, 180, Imagick::FILTER_POINT, 2); リサイズしたさあるけど、劣化激しい・・・
$thumbImg->setImageFormat ("jpeg"); // jpegにする
/* リサイズした画像を保存する */
try {
$thumbImg->writeImage($thumbname); // ファイルとして保存する
$ret = $this->Amazon->putObject("xxxx/".$name, $thumbname); // S3へ保存
if ( $ret !== "" ) {
unlink($thumbname); // 一時ファイル削除
}
$thumbImg->destroy(); // imagickで作成したイメージ削除(これの必要性があまりわかってないけど、メモリ上で残るとかかな?)
} catch (Exception $e) {
echo $e->getMessage();
}
}
AmazonComponent.php
<?php
/**
* AWS SDK for PHP
*
**/
require ROOT. DS . APP_DIR . DS .'Plugin/AmazonSDK/vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Credentials\Credentials;
App::uses('Component', 'Controller');
class AmazonComponent extends Component {
/**
* S3へのファイルアップロード
* @params $key string 保存先パス + ファイル名
* @params $file string 実ファイルのパス
* @return string 保存先
**/
function putObject($key, $file){
try {
$credentials = new Credentials(AWS_S3_KEY, AWS_S3_SECURITY);
$aws = S3Client::factory([
'version' => AWS_S3_VERSION,
'credentials' => $credentials,
'region' => AWS_S3_REGION,
]);
$result = $aws->putObject([
'Bucket' => AWS_S3_BUCKET,
'Key' => $key,
'SourceFile' => $file,
'StorageClass' => AWS_S3_STORAGE,
]);
return $result['ObjectURL'];
} catch (Exception $e) {
echo $e->getMessage();
return "";
}
}
/**
* S3のファイル削除
* @params $file string 保存先パス + ファイル名
* @return void
**/
function removeObject($file){
try {
$credentials = new Credentials(AWS_S3_KEY, AWS_S3_SECURITY);
$aws = S3Client::factory([
'version' => AWS_S3_VERSION,
'credentials' => $credentials,
'region' => AWS_S3_REGION,
]);
$result = $aws->deleteObject([
'Bucket' => AWS_S3_BUCKET,
'Key' => $file
]);
} catch (Exception $e) {
echo $e->getMessage();
}
}
}
その他
ファイルサイズ制限に引っかかる
4MBくらいのサイズのPDFをアップできませんでした。
nginxやphpの設定を見てみると、アップロード制限が指定してあります。
(nginxは1MBとかですね)
その為、設定ファイルを編集し各サービスの再起動が必要です。
$ sudo vim /etc/php.ini
以下の通り書き換える。
/etc/php.ini
max_input_vars = 100000000
upload_max_filesize = 100M
post_max_size = 110M
$ sudo vim /etc/nginx/nginx.conf
以下の通り書き換える。(serverの中じゃ効かないカモです!)
/etc/nginx/nginx.conf
http {
client_max_body_size 200000000;
...
nginxとphpの再起動
$ sudo service nginx -t
$ sudo service nginx -s reload
$ sudo service php-fpm restart
変更履歴
2017/01/06 追記: フォームの内容がある程度の容量を超えるとpostが出来ない
php.iniに「max_input_vars」と「post_max_size」の指定を追加しました。
/etc/php.ini
max_input_vars= 100000000
post_max_size = 110M