ImageMagickを用いたA4サイズのPDF出力

ImageMagickを用いて、画像をA4のPDFに変換する方法を備忘録として。

コマンドconvertに、
・convert -density “解像度(dpi)” -geometry “横幅(px)”x”縦幅(px)” “入力画像名” “出力PDFファイル名”
と指定すると、対応したサイズのPDFファイルが出力される。
PDFファイルは210×297[mm]なので、150dpiであれば、
・横幅:210*150/25.4 ≒ 1240 [px]
・縦幅:297*150/25.4 ≒ 1754 [px]
となり、縦横比を保持する場合のコマンド例は以下となる。

$ convert -density 150 -geometry 1240x1754 input.jpg output.pdf

縦横比を保持しない場合は以下。

$ convert -density 150 -geometry 1240x1754! input.jpg output.pdf

解像度を度々変更し、縦横のpxの算出が面倒な場合には、以下のようなPHPスクリプトを用いる。
(PHPの場合はphp-imagickを用いることも可能だが、ここでは外部プログラムを実行)

<?php
// 指定解像度&サイズのPDF出力

/* -------------------------------------- */
// パラメータ設定
/* -------------------------------------- */
// 画像ファイル名
$f = 'input.jpg';
// 解像度 [dpi]
$dpi = 100;
// 横幅の指定 [mm]
$w = 210;
// 縦幅の指定 [mm]
$h = 297;
/* -------------------------------------- */

/* -------------------------------------- */
// PDFファイルの出力
/* -------------------------------------- */
// [mm] -> [px]
$w = round($w*$dpi/25.4);
$h = round($h*$dpi/25.4);
// コマンド
$cmd = sprintf('convert -density %d -geometry %dx%d! %s output.pdf', $dpi, $w, $h, $f);
// コマンドの実行
exec($cmd);
/* -------------------------------------- */
?>

CentOSでのphp-imagickインストール

CentOSでのphp-imagickのインストールに少々手こずったので、備忘録として。

  • phpのバージョン: 5.3.x
  • ImageMagickのバージョン: 6.7.2.x
  • php-imagickのバージョン: 3.3.0

yumから、下記のパッケージはインストール済みです。

  • ImageMagick
  • ImageMagick-devel
  • ImageMagick-perl

PECLからphp-imagickをインストールしようとすると以下。

# pecl install imagick
downloading imagick-3.3.0.tgz ...
Starting to download imagick-3.3.0.tgz (179,978 bytes)
......................................done: 179,978 bytes
17 source files, building
...
/var/tmp/imagick/imagick.c:3299: error: ‘ZEND_MOD_END’ undeclared here (not in a function)

検索すると、「pcreなどがPHPcoreに統合されたために」、などが見つかる。
ソースコードの該当の箇所を修正する必要があると考え、別の方法をとることに。

PECLでローカルにダウンロードして、makeすると同様のエラーが出ることを確認する。

$ mkdir ~/imagick
$ cd ~/imagick
$ sudo pecl download imagick
Starting to download imagick-3.3.0.tgz (179,978 bytes)
......................................done: 179,978 bytes
File /home/***/imagick/imagick-3.3.0.tgz downloaded
$ tar xvfz imagick-3.3.0.tgz
$ cd imagick-3.3.0
$ sudo phpize
$ sudo ./configure
$ sudo make
...
/home/***/imagick/imagick-3.3.0/imagick.c:3299: error: ‘ZEND_MOD_END’ undeclared here (not in a function)
make: *** [imagick.lo] エラー 1

そして、imagick.cの、該当行を修正。
(“ZEND_MOD_END”は存在しない参照なので、”{NULL, NULL, NULL}”とする)

3298 #endif
3299         // ZEND_MOD_END
3300         {NULL, NULL, NULL}
3301 };
3302 #endif

改めて、makeからインストールを続行。
php.iniには「extension=imagick.so」を追加する。

$ sudo make
...
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.
$ sudo make test
$ sudo make install
$ sudo vi /etc/php.ini
$ sudo service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [  OK  ]

インストールの確認として、以下で「imagick」の行を探す。

$ php -m | grep imagick
imagick

見つかれば、インストールは無事に完了している。

20151019

Jetpack「Beautiful Math」による LaTeX 数式挿入検討 (すぐに中止)

Jetpackの「Beautiful Math」で数式が挿入できるということで他のプラグインと検証。
と思ったのですが、数式中で改行できない、ということで検証を早々に中止。

現在の数式挿入で使用しているプラグイン「WP QuickLaTeX」では、以下のようなコードで良い。

[latex]
\left\{
\begin{aligned}
F(\omega) &= \int_{-\infty}^\infty f(t)e^{-j\omega t} dt \\
f(t) &= \frac{1}{2\pi} \int_{-\infty}^\infty F(\omega)e^{j\omega t} d\omega
\end{aligned}
\right.
[/latex]

このコードで、以下のように。

 \left\{  \begin{aligned}   F(\omega) &= \int_{-\infty}^\infty f(t)e^{-j\omega t} dt \\   f(t) &= \frac{1}{2\pi} \int_{-\infty}^\infty F(\omega)e^{j\omega t} d\omega  \end{aligned} \right.

この数式が、Jetpackの「Beautiful Math」でどうなるか試そうと思ったのですが、
$latex ***$
の間では現状改行ができないそうなので断念。
数式の途中改行ができるようになってから改めて比較したいです。

\left\{
 \begin{aligned}
  F(\omega) &= \int_{-\infty}^\infty f(t)e^{-j\omega t} dt \\
  f(t) &= \frac{1}{2\pi} \int_{-\infty}^\infty F(\omega)e^{j\omega t} d\omega
 \end{aligned}
\right.

投稿時点でのJetpackのバージョン: 3.7.2

Mandelbrot2

Matlab で マンデルブロ集合

息抜きで、Matlabでマンデルブロ集合の図形を描写するプログラムを作成してみました。

マンデルブロ集合とは

マンデルブロ集合は、Wikipediaから以下です。

次の漸化式で定義される複素数列\{z_n\}_{n \in \mathrm{N}}n\to\inftyの極限で無限大に発散しないという条件を満たす複素数c全体が作る集合がマンデルブロ集合である。
(Wikipediaより引用)

     \[ \left\{ \begin{aligned} z_{n+1} &= {z_n}^2 + c \\ z_0 &= 0 \end{aligned} \right. \]

ざっくりとしたプログラムの解説としては、複素平面座標にて、その複素数の発散の度合いで図形が描ける、というものです。

ソースコード

実際のソースコードは以下です。

複素平面にて描写範囲を指定し、各座標の複素数Cの発散を調べています。
絶対値が2以上になった場合を発散しているとし、その発散回数を保存しています。
図形の描写では、各座標の発散までの計算回数をプロットしています。
(変数は単精度で計算しています)

% ----------------------------------------------------- %
% パラメータ設定
% ----------------------------------------------------- %
% 最大ループ回数
loop = 1e2;
% 各軸の描写点数
n    = 1e3;
% 描写範囲
xmin = -1.5;
xmax = 0.5;
ymin = -1.0;
ymax = 1.0;
% ----------------------------------------------------- %

% ----------------------------------------------------- %
% マンデルブロ集合の計算
% ----------------------------------------------------- %
% 座標設定
x = single(linspace(xmin,xmax,n));
y = single(linspace(ymin,ymax,n));
C = ones(n,1)*x + 1i*y(:)*ones(1,n);
% マンデルブロ図形の計算
Z = zeros(n,'single');
W = zeros(n,'single');
% インデックスの初期値
index = true(size(C));
% ループ
for k = 1:loop
    Z(index) = Z(index).^2 + C(index);
    index = abs(Z) < 2;
    W(~index & W==0) = k;
end
W(W==0) = loop+1;
% 図形のプロット
imagesc(x,y,W);
axis square;
title('Mandelbrot Set');
xlabel('Real');
ylabel('Imag');
% PNG 画像の保存
print('Mandelbrot.png', '-dpng');
% ----------------------------------------------------- %

このソースコードで描いてみた図形が以下。

Mandelbrot1

描写位置を変更すると面白いです。

Mandelbrot2

Mandelbrot3

git初心者による初心者なりのメモ

元々svn歴1年間、今のところgit歴約1週間くらいです。
gitを使用する目的は、
・個人的な、ソースコードのバージョン管理(開発に使用するPCが多いため)
・さくらレンタルサーバーにsvnを導入するのはめんどくさそう
・使っている人が多そう
程度です。

今のところ、第1の目的は果たしているので、初心者による初心者なりのメモです。
間違っている可能性も高いです。

    下記のメモの簡単な補足

  • sshのconfigに、sakuraというホストを登録しています
  • セットアップ例は、こちら
  • リモートのリポジトリは、~/git/repos.git/
  • ローカルのリポジトリは、~/local/git/
  • リモートはさくらのレンタルサーバー、ローカルはCygwin環境

まず最初にローカルに複製

ローカルリポジトリを複製しています。
複製例なので、出来立て空っぽのリポジトリです(Warningはそれが原因)。

$ cd ~/local/git/
$ git clone sakura:~/git/repos.git .
Cloning into '.'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.

最初のコミット

空っぽのREADMEファイルを作成してコミットし、プッシュしておきます。

$ touch ERADME
$ git add README
$ git commit -m "最初のコミット"
[master (root-commit) ***] 最初のコミット
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode *** README

これで、ブランチを確認すると、以下のようになります。

$ git branch
* master

ローカルのブランチでの編集

gitがsvnと異なる特徴の一つが、
「コミットをローカルで行うことができる」
だと思っています。
なので、リモートのmasterリポジトリを毎回書き換えるのではなく、ローカルにlocalというブランチを作成し、区切りが良いところでmasterに合流させる、という方法を取ります。

まずは、ローカルブランチlocalの作成

$ git branch local

ブランチを確認すると以下のように増えています。

$ git branch
  local
* master

ここで、ローカルブランチに切り替えます。

$ git checkout local
Switched to branch 'local'

あとは、以下のように色々と変更を加えてコミットしていった後とします。

$ git branch
* local
  master

$ git log
commit ***
Author: user <mail>
Date:   ***

    index.phpの編集

commit ***
Author: user <mail>
Date:   ***

    index.phpの作成

commit ***
Author: user <mail>
Date:   ***

    最初のコミット

この時点でmasterリポジトリに切り替えると、以下のように変更点に差が発生しています。

$ git checkout master
Switched to branch 'master'
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

$ git show-branch
! [local] index.phpの編集
 * [master] 最初のコミット
--
+  [local] index.phpの編集
+  [local^] index.phpの作成
+* [master] 最初のコミット

そこで、masterブランチに、localブランチの変更点をマージさせます。
(マージという単語の使い方が正しくないかもしれませんが)

$ git merge local
Updating ***
Fast-forward
 index.php | 2 ++
 1 file changed, 2 insertions(+)
 create mode *** index.php

すると、両方のブランチの変更点が一緒になっていることが分かります。
ここで、リモートリポジトリにmasterリポジトリをプッシュしておきます。

$ git show-branch
! [local] index.phpの編集
 * [master] index.phpの編集
--
+* [local] index.phpの編集

$ git push origin master
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (8/8), 739 bytes | 0 bytes/s, done.
Total 8 (delta 0), reused 0 (delta 0)
To sakura:~/git/repos.git
 * [new branch]      master -> master

この時点でタグを追加したい場合は以下とします。
タグv0.01を作成して、タグ一覧をリモートリポジトリにプッシュしています。

$ git tag v0.01
$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To sakura:~/git/repos.git
 * [new tag]         v0.01 -> v0.01

別のローカル環境での同期

先ほどは、masterリポジトリにlocalリポジトリをマージしていました。
別のローカル環境では、最初にmasterリポジトリに変更点を反映させる必要があるため、以下のようにします。

ここでは、masterリポジトリにチェックアウトしてから、リモートから変更点を反映しています。

$ git checkout master
$ git fetch
$ git merge

そして、masterブランチからlocalブランチにマージすれば完了です。

$ git checkout local
$ git merge master

よく使っているコマンドダイジェスト

基本的に、以下のコマンドですべて事足りているのと、今後も事足りそうです。
個人的にしか使っていないので、今のところ今後も増えそうに無いです。
グループで管理する必要がある場合には、色々とセオリーの勉強が必要になりそう。

  • git checkout local で、localブランチにチェックアウト
  • git add と git rm と git mv で、各種ファイルの追加や削除、移動
  • git commit -m “コメント” でコメント付きでコミット
  • git push origin master で、masterブランチをプッシュ
  • git fetch からの git merge:リモートリポジトリから変更点を反映
  • git branch で現在のブランチの確認
  • git show-branch で、各ブランチの情報
  • git status で現在の状態確認
  • git diff で直後のコミットとの差分表示(コミット前)

さくらレンタルサーバーでの git のリモートリポジトリ作成

以下、備忘録として、さくらレンタルサーバーでの git のリモートリポジトリ作成について。
すでに、csh 環境から bash 環境に変更されていることを前提にしています。

参考サイトとほぼほぼ同じ手順ですが、さくらでの git のインストールは不必要でした。
また、ローカルの環境は cygwin 環境です。

リモート側のセットアップ

さくらでのリモートリポジトリを作成します。
--bare で作業用ディレクトリ無しで初期化しています。

$ mkdir -p $HOME/git/repos.git
$ cd $HOME/git/repos.git
$ git init --bare
Initialized empty Git repository in /home/example/git/repos.git/

クライアント側のセットアップ

クライアント側で適当にコミットしてみます。

まずは初期化。
ホームディレクトリ直下に、適当なフォルダ git を作成しています。

$ cd $HOME
$ mkdir git
$ cd git

次に、空のテキストファイルを作成して、コミット。

$ touch README
$ git add README
$ git commit -m "initial commit"

初めて使用する環境の場合、以下のようなエラーが発生するかもしれません。
指示されている通り、特定できるようにユーザー名やメールアドレスを設定すれば、問題なくコミットできるようになるはずです。

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got '***')

コミットが成功すれば、以下のようにリモートリポジトリを追加し、プッシュするだけです。

$ git remote add origin sakura:~/git/repos.git
$ git push origin master

ここでは、すでに以下の config のようにホスト名を登録しています。

Host sakura
	HostName			example.sakura.ne.jp
	User				example
	IdentityFile		~/.ssh/id_rsa.sakura.ne.jp
	ServerAliveInterval	20
	ServerAliveCountMax	3

未登録の場合には、以下のようにユーザー名やサーバー名の指定が必要になります。

$ git remote add origin example@example.sakura.ne.jp:~/git/repos.git
$ git push origin master

さくらレンタルサーバーでの文字化けの解消、bash 環境への変更

以下、備忘録として、さくらレンタルサーバーでの文字化けの解消、bash 環境への変更方法について。

SSH の設定

まずは、初期パスワードを変更します。32文字の記号を含んだランダムな文字列に。
次に、鍵ファイルを生成し、公開鍵を登録し、ローカルの config を設定。

Host sakura
	HostName			user.sakura.ne.jp
	User				user
	IdentityFile		~/.ssh/id_rsa.sakura.ne.jp
	ServerAliveInterval	20
	ServerAliveCountMax	3

さくらの csh 環境を調整

さくらは FreeBSD なので、vim の文字化けが発生しないように csh 環境を調整。
ただし、この後で bash 環境に変更をします。

# $FreeBSD: src/share/skel/dot.cshrc,v 1.14.6.1 2008/11/25 02:59:29 kensmith Exp $
#
# .cshrc - csh resource script, read at beginning of execution by each shell
#
# see also csh(1), environ(7).
#

alias h		history 25
alias j		jobs -l
alias la	ls -a
alias lf	ls -FA
alias ll	ls -lA
alias vi	"jvim3 -K TTT -k t"

# A righteous umask
umask 22

set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/bin)

#setenv	EDITOR	vi
setenv  EDITOR	jvim3
setenv  LANG	ja_JP.UTF-8
setenv	PAGER	more
setenv	BLOCKSIZE	K
setenv	PKG_DBDIR	~/db/pkg

if ($?prompt) then
	# An interactive shell -- set some stuff up
	set filec
	set history = 100
	set savehist = 100
	set mail = (/var/mail/$USER)
	if ( $?tcsh ) then
		bindkey "^W" backward-delete-word
		bindkey -k up history-search-backward
		bindkey -k down history-search-forward
	endif
endif

さくらに bash 環境を構築

まずは、bash_profile ファイルの作成。

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

# User specific environment and startup programs
PATH=$PATH:$HOME/bin

export PATH

次に、.bashrc ファイルを作成。
エイリアスは、.cshrc と同様で、vim が文字化けしないように設定しています。

# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

# User specific aliases and functions
alias h='history 25'
alias j='jobs -l'
alias la='ls -a'
alias lf='ls -FA'
alias ll='ls -lA'
alias vi='jvim3 -K TTT -k t'

# A righteous umask
umask 22

export EDITOR=jvim3
export LANG=ja_JP.UTF-8
export PAGER=more
export BLOCKSIZE=K
export PKG_DBDIR=~/db/pkg

最後に、csh 環境で以下のコマンドを入力することで、bash 環境に変更されます。

chsh -s /usr/local/bin/bash

楽天市場における順序不定

楽天商品検索API 関連の案件を終えて。

今まで気づいていませんでしたが、楽天市場における表示順序は不定なんですね。

たとえば、同じショップにおける価格100円の商品が全部で40件だとすると、同条件の表示順序が不定なので、
・1ページ目に商品A
・2ページ目にも商品A
ということがたまに発生します。
40件の商品すべての結果を得るには、
・商品をユニークに配列に登録
・検索結果の件数が40未満の場合には再度検索
などの方法しか無いのでしょうか。。

考えても良い案が浮かばなかったので挫折しました。


追記(2015/08/10)
結局、ID別の連想配列で管理し、countと合わない間はループ、という仕様にしてしまいました。