Category Archives: Python

PDF作成ツール「reportlab」で「つちよし」を出力してみた

仕事で人名漢字を使いたい!ということで
色々調査しておりました

・Mysqlで保存、取り出し
・Excel出力
・PDF出力
などなど

今回はPDF出力で調査した内容をメモっておきたいと思います

前提として、
・windows(64bit)
・python2.7
・試すのは「つちよし」吉の士が土になっているやつ
・PDF出力にはreportlab
・フォントはipa明朝(ipamjm.ttf)
です

まずは
https://pypi.python.org/pypi/reportlab
から
reportlab-3.3.0-cp27-none-win_amd64.whlを落とします

解凍して、所定の場所に格納(お使いの環境でpythonのパッケージが入っているとこ)

フォントの入手方法は割愛します

[code lang=”py”]
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont #ipaのフォント使う時に必要
from reportlab.lib.units import cm #単位

pdfFile = canvas.Canvas("任意の場所/hoge.pdf")
pdfFile.saveState()

作成者

pdfFile.setAuthor("ちろぶろ")

タイトル

pdfFile.setTitle("つちよし")

サブタイトル

pdfFile.setSubject("出力するよー!")

pdfのサイズ A4

pdfFile.setPageSize((21.0cm,29.7cm))

フォント IPA明朝

fontname = "IPAmjMincho"

フォントファイルの場所

pdfmetrics.registerFont(TTFont(fontname, ‘任意の場所/ipamjm.ttf’))

pdfFile.setFont(fontname, 30)

文字書き込み

pdfFile.drawString(5cm,25cm,"?")

pdfFile.restoreState()

PDF出力

pdfFile.save()

[/code]
以上でPDFの出力は出来ます!
さぁやってみましょー!

・・・いかがでしたでしょうか
文字化けしますよね!

これだけでは、「つちよし」が出力出来ません

「つちよし」はサロゲートペア対象文字なので
python上で扱う際には
\uD842\uDFb7
てな感じで2文字の扱いを受けます
サロゲートペアについての説明は割愛します

それをそのままPDFに書き込んでいるので
\uD842に対応する文字
\uDFB7に対応する文字
の2文字を出力してしまっています

これは困った・・・
ということで
解凍したreportlabフォルダの中の
reportlab/pdfbase/ttfonts.py
の中を少しいじります

splitStringという関数を探してください
[code lang=”py”]
def splitString(self, text, doc, encoding=’utf-8′):
asciiReadable = self._asciiReadable
try: state = self.state[doc]
except KeyError: state = self.state[doc] = TTFont.State(asciiReadable)
curSet = -1
cur = []
results = []
temp_code = 0
if not isUnicode(text):
text = text.decode(‘utf-8’) # encoding defaults to utf-8
a = {}
a["test"] = text
print len(text)
assignments = state.assignments
subsets = state.subsets
for code in map(ord,text):
if code in assignments:
n = assignments[code]
else:
if state.frozen:



[/code]
この部分に少し付け加えます
変更前
[code lang=”py”]
subsets = state.subsets
for code in map(ord,text):
if code in assignments:
n = assignments[code]
[/code]
変更後
[code lang=”py”]
temp_code = 0
for code in map(ord,text):
if 0xD800 < code < 0xDBFF:
temp_code = code
continue
elif 0xDC00 < code < 0xDFFF:
code = 0x10000 + (temp_code – 0xD800) * 0x400 + (code – 0xDC00)
[/code]

何をしているかというと、
上位サロゲート(U+D800 ~ U+DBFF)が来た場合には、コードを保持し、その後の処理は行わない
下位サロゲート(U+DC00 ~ U+DFFF)が来た場合には、保持した上位サロゲートを使って
元の文字コードを生成しています

temp_codeにD842
codeにDFB7を入れて計算してもらうと
20BB7という値になるはずです(「つちよし」の文字コード)

この20BB7を処理で使用することで、「つちよし」を出力出来るようにします

PDFを出力してみてください!
上手くいったでしょうか?

css3 filter とpython(blur編)

前説はこちら

今回はblurについて記載する

アプリ上では

hoge.style.webkitFilter = "blur(10px)";

サーバー上では

im = np.array(input_image)
im2 = np.zeros(im.shape)
for i in range(3):
im2[:,:,i] = ndimage.filters.gaussian_filter(im[:,:,i],s)
misc.imsave(uploadfilepath,im2.astype('uint8'))
output_image = Image.open(uploadfilepath).convert("RGBA")

以上
numpy、scipyを使用する
sに指定した値を入れる
今回は10

これで一通り説明し終わった
ネットでこの手の検索をするとOpenCVがかなりの数を占めていた様な気がする
実際に使ってはないので、どういうものかは分かっていないが、見た目にずれがおこる様な気はしている
ImageMagickも使ってみたが、同じ結果にならない(目で見て)、blurに関して言うと
速度もかなり遅かった
見た目を同じにするには同じ計算をした方が良いと判断し(物による)、今回の件に至った

やり方違っているよ!等あればどしどし、コメントよろしく

css3 filter とpython(contrast編)

前説はこちら

今回はcontrastについて記載する

アプリ上では
hoge.style.webkitFilter = “contrast(50%)”;

サーバー上では

brightness_converter = ImageEnhance.Contrast(input_image)
output_image = brightness_converter.enhance(s)

以上
PILにcontrastの関数があったので、何もしなくてよい
sにcontrastの値を入れる今回は0.5

次回は、blur!

css3 filter とpython(brightness編)

前説はこちら

今回はbrightnessについて記載する

アプリ上では
hoge.style.webkitFilter = “brightness(0.5)”;

サーバー上では

brightness_converter = ImageEnhance.Brightness(input_image)
output_image = brightness_converter.enhance(s)

以上
PILにbrightnessの関数があったので、何もしなくてよい
sにbrightnessの値を入れる今回は0.5

次回は、contrast!

css3 filter とpython(opacity編)

前説はこちら

今回はopacityについて記載する

アプリ上では
hoge.style.webkitFilter = “opacity(0.5)”;

サーバー上では

w,h = input_image.size
white_image = Image.new(“RGBA”, (w, h),(0xFF,0xFF,0xFF,s))
output_image = input_image
output_image.paste(white_image, (0,0) ,white_image.split()[3])

以上
何をしたかというと白い画像を新しく作成して、上に重ねただけ
opacityの値によってsの値を変える
今回は0.5なので128とした

次回は、brightness!

css3 filter とpython(invert編)

前説はこちら

今回はinvertについて記載する

アプリ上では
hoge.style.webkitFilter = “invert(100%)”;

サーバー上では

output_image = input_image.point(lambda i: 255- i)

以上

valueの値はW3Cのサイト
http://www.w3.org/TR/filter-effects/
を参考に算出した
今回は100%の反転だったので255-実際の値となる
次回は、opacity!

css3 filter とpython(hue-rotate編)

前説はこちら

今回はhue-rotateについて記載する

アプリ上では
hoge.style.webkitFilter = “hue-rotate(180deg)”;

サーバー上では

value = (-0.574, 1.43, 0.144, 0,
0.426, 0.43, 0.144, 0,
0.426, 1.43, -0.856, 0)
output_image = Image.open(uploadfilepath).convert(“RGB”,value)

以上

valueの値はW3Cのサイト
http://www.w3.org/TR/filter-effects/
を参考に算出した
式は
[ [ [ [
a00 a01 a02 +0.213 +0.715 +0.072 +0.787 -0.715 -0.072 -0.213 -0.715 +0.928
a10 a11 a12 = +0.213 +0.715 +0.072 + cos(s) * -0.213 +0.285 -0.072 + sin(s) * +0.143 +0.140 -0.283
a20 a21 a22 +0.213 +0.715 +0.072 -0.213 -0.715 +0.928 -0.787 +0.715 +0.072
] ] ] ]
である
sに指定したdegを当てはめて計算する
今回は180degなのでcos(180) = -1とsin(180) = 0を計算に使用
Pil上では4*3の行列でconvertするので全ては使用しないが、見た目は同じになった

次回は、invert!

css3 filter とpython(saturate編)

前説はこちら

今回はsaturateについて記載する

アプリ上では
hoge.style.webkitFilter = “saturate(500%)”;

サーバー上では

value = (4.148, -2.86, -0.288, 0,
-0.852, 2.14, -0.288, 0,
-0.852, -2.86, 4.712, 0)
output_image = Image.open(uploadfilepath).convert(“RGB”,value)

以上

valueの値はW3Cのサイト
http://www.w3.org/TR/filter-effects/
を参考に算出した
式は
values=”(0.213 + 0.787 * s) (0.715 – 0.715 * s) (0.072 – 0.072 * s) 0 0
(0.213 – 0.213 * s) (0.715 + 0.285 * s) (0.072 – 0.072 * s) 0 0
(0.213 – 0.213 * s) (0.715 – 0.715 * s) (0.072 + 0.928 * s) 0 0
0 0 0 1 0″
である
sに指定した%を当てはめて計算する
今回は500%なので5になる(50%なら0.5)
Pil上では4*3の行列でconvertするので全ては使用しないが、見た目は同じになった

次回は、hue-rotate!

css3 filter とpython(sepia編)

前説はこちら

今回はsepiaについて記載する

アプリ上では

hoge.style.webkitFilter = "sepia(100%)";

サーバー上では

value = (0.393,0.769,0.189,0,
0.349,0.686,0.168,0,
0.272,0.534,0.131,0)
output_image = Image.open(uploadfilepath).convert("RGB",value)

以上

valueの値はW3Cのサイト
http://www.w3.org/TR/filter-effects/
を参考に算出した

式としては
values=”(0.393 + 0.607 * [1 – amount]) (0.769 – 0.769 * [1 – amount]) (0.189 – 0.189 * [1 – amount]) 0 0
(0.349 – 0.349 * [1 – amount]) (0.686 + 0.314 * [1 – amount]) (0.168 – 0.168 * [1 – amount]) 0 0
(0.272 – 0.272 * [1 – amount]) (0.534 – 0.534 * [1 – amount]) (0.131 + 0.869 * [1 – amount]) 0 0
0 0 0 1 0″
である
amountに指定した%を当てはめて計算する(50%だったら0.5)
Pil上では4*3の行列でconvertするので全ては使用しないが、見た目は同じになった

次回は、saturate!

css3 filter とpython(grayscale編)

前説はこちら

今回はgrayscaleについて記載する
grayscaleは簡単だったが一通り説明する

アプリ上では

hoge.style.webkitFilter = "grayscale(100%)";

こんだけ

次にサーバー側の処理

まず取得した画像をサーバー上のどこかに保存(ここは省く)
そのパスuploadfilepathとする

1.保存したパスから画像を取得する
input_image = Image.open(uploadfilepath).convert(“RGBA”)

2.convertする
output_image = input_image.convert(‘L’)

以上(笑)

1については、他のフィルターとの兼ね合いもあるので、入れているが
grayscaleだけを行う場合は
output_image = Image.open(uploadfilepath).convert(“L”)
でよい
100%じゃない時どうするの?ってのも分かっているので
知りたい人がいそうなら記載する

次回はsepiaの説明!