Python
pixiv
Python3
pillow

pixiv のデイリーランキング上位イラストをコラージュ加工するプログラムの開発


1. はじめに

 pixiv のデイリーランキング上位イラストをコラージュ加工し,1 枚の画像データとして出力したいと考えていた。しかし,適当なプログラムが見つからなかったため Python を用いて開発することとなった。本記事では,開発したプログラムのソースコードと,その実行結果について記述する。

 続く 2 章では,開発・実行環境について記述する。3 章では,プログラムのソースコードについて記述する。4 章では,プログラムの実行結果について記述する。5 章では,本記事のまとめと今後の展望について記述する。


2. 環境情報

 次章以降で行う作業は以下の環境下で行ったものである。


  • Pillow Ver.5.3.0 ※

  • PixivPy Ver.3.3.5 ※

  • pip3 Ver.9.0.1

  • Python Ver.3.6.7

  • Linux Kernel Ver.4.15.0-43-generic

 ※ 外部ライブラリのため,別途インストールが必要である


3. ソースコード

 プログラムのソースコードを以下に示す。

01 | #!/usr/bin/env python3

02 | # -*- coding: utf-8 -*-
03 |
04 | from functools import reduce
05 | from PIL import Image
06 | from pixivpy3 import *
07 | import requests
08 |
09 | def combine_imgs(
10 | _img_center,
11 | _img_top=Image.new('RGB', (0, 0)),
12 | _img_right=Image.new('RGB', (0, 0)),
13 | _img_bottom=Image.new('RGB', (0, 0)),
14 | _img_left=Image.new('RGB', (0, 0))
15 | ):
16 | dst_img_width = _img_center.width + _img_right.width + _img_left.width
17 | dst_img_height = _img_center.height + _img_top.height + _img_bottom.height
18 | dst_img = Image.new('RGB', (dst_img_width, dst_img_height))
19 | dst_img.paste(_img_left, (0, _img_top.height))
20 | dst_img.paste(_img_center, (_img_left.width, _img_top.height))
21 | dst_img.paste(_img_right, (_img_left.width + _img_center.width, _img_top.height))
22 | dst_img.paste(_img_top, (_img_left.width, 0))
23 | dst_img.paste(_img_bottom, (_img_left.width, _img_top.height + _img_center.height))
24 | return dst_img
25 |
26 | if __name__ == '__main__':
27 | ID = "[ID]"
28 | PW = "[PASSWORD]"
29 | DST_IMG_WIDTH_PX = 1920
30 | DST_IMG_HEIGHT_PX = 1080
31 | DIVISION_NUM = 5
32 | RECTANGLE_IMG_HEIGHT = int(DST_IMG_HEIGHT_PX / DIVISION_NUM)
33 |
34 | pixiv_api = PixivAPI()
35 | pixiv_api.login(ID, PW)
36 | json = pixiv_api.ranking(ranking_type='illust')
37 |
38 | response_packet = list(map(
39 | lambda x: requests.get(
40 | x.work.image_urls['large'],
41 | headers={'Referer': 'https://app-api.pixiv.net/'},
42 | stream=True
43 | ), json.response[0].works
44 | ))
45 |
46 | material_imgs = list(map(lambda x: Image.open(x.raw), response_packet))
47 |
48 | resized_material_imgs = list(map(
49 | lambda x: x.resize((
50 | int(x.width * RECTANGLE_IMG_HEIGHT / x.height),
51 | RECTANGLE_IMG_HEIGHT
52 | )), material_imgs
53 | ))
54 |
55 | material_imgs_with_frame = list(map(
56 | lambda x: combine_imgs(
57 | _img_center=x,
58 | _img_top=Image.new('RGB', (x.width, 5)),
59 | _img_right=Image.new('RGB', (5, x.height)),
60 | _img_bottom=Image.new('RGB', (x.width, 5)),
61 | _img_left=Image.new('RGB', (5, x.height))
62 | ), resized_material_imgs
63 | ))
64 |
65 | material_imgs_with_frame.reverse()
66 |
67 | rectangle_imgs = list()
68 | for i in range(len(material_imgs_with_frame)):
69 | if len(material_imgs_with_frame) < 2: break
70 | first_img = material_imgs_with_frame.pop()
71 | second_img = material_imgs_with_frame.pop()
72 | if first_img.width < DST_IMG_WIDTH_PX:
73 | material_imgs_with_frame.append(
74 | combine_imgs(_img_center=first_img, _img_right=second_img)
75 | )
76 | else:
77 | rectangle_imgs.append(
78 | first_img.resize((DST_IMG_WIDTH_PX, RECTANGLE_IMG_HEIGHT))
79 | )
80 | material_imgs_with_frame.append(second_img)
81 |
82 | dst_img = reduce(
83 | lambda x, y: combine_imgs(
84 | _img_center=x,
85 | _img_bottom=y
86 | ), rectangle_imgs[:DIVISION_NUM]
87 | )
88 |
89 | dst_img_with_frame = combine_imgs(
90 | _img_center=dst_img,
91 | _img_top=Image.new('RGB', (dst_img.width, 5)),
92 | _img_right=Image.new('RGB', (5, dst_img.height)),
93 | _img_bottom=Image.new('RGB', (dst_img.width, 5)),
94 | _img_left=Image.new('RGB', (5, dst_img.height))
95 | )
96 |
97 | resized_dst_img = dst_img_with_frame.resize((DST_IMG_WIDTH_PX, DST_IMG_HEIGHT_PX))
98 | resized_dst_img.save('dst.png')

 27・28 行目は,各自の pixiv ID とパスワードに置き換える必要がある


4. 実行結果

 プログラムを執筆時点(2019/01/02)で実行した結果を以下に示す。


5. おわりに

 本記事では,pixiv のデイリーランキング上位イラストをコラージュ加工するプログラムのソースコードと,その実行結果について記述してきた。しかし,今回開発したプログラムは実行したタイミングによっては画像の比が崩れてしまうことがある。今後は,1 〜 50 位のイラストを 1 枚の画像としてコラージュ加工できるようにプログラムを改良していきたいと考えている。


参考情報