about summary refs log tree commit diff stats
path: root/designer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'designer.cpp')
-rw-r--r--designer.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/designer.cpp b/designer.cpp new file mode 100644 index 0000000..8d803bf --- /dev/null +++ b/designer.cpp
@@ -0,0 +1,181 @@
1#include "designer.h"
2#include <dirent.h>
3#include <sstream>
4#include <iostream>
5
6designer::designer(
7 std::string imagesDir) :
8 colDist_ {0, 1, 100, 30, 5, 1, 1}
9{
10 DIR* imgdir;
11 struct dirent* ent;
12 if ((imgdir = opendir(imagesDir.c_str())) == nullptr)
13 {
14 throw std::invalid_argument("Couldn't find images");
15 }
16
17 int maxStripLen = 0;
18 std::map<int, int> stripLength;
19
20 while ((ent = readdir(imgdir)) != nullptr)
21 {
22 std::string dname(ent->d_name);
23 std::stringstream nameParse;
24 int stripNum;
25 int panelNum;
26 char sep;
27 std::string ext;
28
29 nameParse << dname;
30
31 if (nameParse >> stripNum &&
32 nameParse >> sep &&
33 nameParse >> panelNum &&
34 nameParse >> ext &&
35 ext == ".png")
36 {
37 if (!stripLength.count(stripNum) || stripLength[stripNum] < panelNum)
38 {
39 stripLength[stripNum] = panelNum;
40 }
41
42 if (panelNum > maxStripLen)
43 {
44 maxStripLen = panelNum;
45 }
46
47 comics_[stripNum][panelNum] = imagesDir + "/" + dname;
48 }
49 }
50
51 closedir(imgdir);
52
53 std::vector<int> lenHist(maxStripLen, 0);
54 for (const auto& mapping : stripLength)
55 {
56 lenHist[mapping.second]++;
57 }
58
59 lenDist_ =
60 std::discrete_distribution<int>(
61 std::begin(lenHist),
62 std::end(lenHist));
63}
64
65Magick::Image designer::generate(std::mt19937& rng) const
66{
67 int numPanels = lenDist_(rng);
68 std::vector<Magick::Image> panels;
69
70 int numCols = std::min(colDist_(rng), numPanels);
71
72 int curCol = 0;
73 int numRows = 0;
74 int curRowWidth = 0;
75 int maxRowWidth = 0;
76
77 std::map<int, int> rowHeight;
78 int curRowHeight = 0;
79
80 for (int i = 0; i < numPanels; i++)
81 {
82 if (curCol == 0)
83 {
84 numRows++;
85 }
86
87 std::uniform_int_distribution<int> stripPick(1, comics_.size());
88 int stripNum = stripPick(rng);
89 const auto& strip = comics_.at(stripNum);
90
91 size_t low = i / static_cast<double>(numPanels) * strip.size();
92 size_t high = (i+1) / static_cast<double>(numPanels) * strip.size();
93 std::uniform_int_distribution<int> panelPick(
94 low,
95 std::min(high, strip.size() - 1));
96
97 int panelNum = panelPick(rng) + 1;
98 const std::string& panel = strip.at(panelNum);
99
100 std::cout << panel << std::endl;
101
102 Magick::Image curfile(panel);
103 curfile.borderColor("black");
104 curfile.backgroundColor("black");
105
106 if (std::bernoulli_distribution(1.0 / 50.0)(rng))
107 {
108 std::normal_distribution<double> rotDist(0.0, 20.0);
109 double rotAmt = rotDist(rng);
110
111 curfile.rotate(rotAmt);
112 }
113
114 if (std::bernoulli_distribution(1.0 / 2.0)(rng))
115 {
116 std::geometric_distribution<unsigned int> borderDist(1.0 / 8.0);
117 curfile.border(
118 Magick::Geometry{
119 borderDist(rng),
120 borderDist(rng)});
121 }
122
123 curRowWidth += curfile.columns();
124
125 if (curfile.rows() > curRowHeight)
126 {
127 curRowHeight = curfile.rows();
128 }
129
130 panels.emplace_back(std::move(curfile));
131
132 curCol++;
133
134 if (curCol >= numCols || (i == numPanels - 1))
135 {
136 if (curRowWidth > maxRowWidth)
137 {
138 maxRowWidth = curRowWidth;
139 }
140
141 rowHeight[numRows - 1] = curRowHeight;
142
143 curCol = 0;
144 curRowWidth = 0;
145 curRowHeight = 0;
146 }
147 }
148
149 int fileHeight = 0;
150 for (const auto& mapping : rowHeight)
151 {
152 fileHeight += mapping.second;
153 }
154
155 Magick::Image result{
156 Magick::Geometry(maxRowWidth, fileHeight),
157 "black"};
158
159 int curx = 0;
160 int cury = 0;
161 int thisCol = 0;
162 int thisRow = 0;
163 for (const Magick::Image& panel : panels)
164 {
165 if (thisCol == numCols)
166 {
167 thisCol = 0;
168 cury += rowHeight.at(thisRow);
169 thisRow++;
170 curx = 0;
171 }
172
173 result.composite(panel, curx, cury);
174
175 curx += panel.columns();
176
177 thisCol++;
178 }
179
180 return result;
181}