File: | /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp |
Warning: | line 929, column 37 The left operand of '>' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* ============================================================ | |||
2 | * | |||
3 | * This file is a part of digiKam project | |||
4 | * https://www.digikam.org | |||
5 | * | |||
6 | * Date : 2012-10-18 | |||
7 | * Description : Auto Crop analyzer | |||
8 | * Algorithm based on black point detection on | |||
9 | * the basis of spiral traversal | |||
10 | * | |||
11 | * SPDX-FileCopyrightText: 2013 by Sayantan Datta <sayantan dot knz at gmail dot com> | |||
12 | * SPDX-FileCopyrightText: 2013-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> | |||
13 | * | |||
14 | * SPDX-License-Identifier: GPL-2.0-or-later | |||
15 | * | |||
16 | * ============================================================ */ | |||
17 | ||||
18 | #include "autocrop.h" | |||
19 | ||||
20 | // C++ includes | |||
21 | ||||
22 | #include <cmath> | |||
23 | #include <cfloat> | |||
24 | ||||
25 | // Qt includes | |||
26 | ||||
27 | #include <QTextStream> | |||
28 | #include <QFile> | |||
29 | #include <QPoint> | |||
30 | #include <QColor> | |||
31 | ||||
32 | // Local includes | |||
33 | ||||
34 | #include "digikam_debug.h" | |||
35 | ||||
36 | namespace Digikam | |||
37 | { | |||
38 | ||||
39 | class Q_DECL_HIDDEN__attribute__((visibility("hidden"))) AutoCrop::Private | |||
40 | { | |||
41 | public: | |||
42 | ||||
43 | Private() = default; | |||
44 | ||||
45 | QRect cropArea; | |||
46 | }; | |||
47 | ||||
48 | AutoCrop::AutoCrop(DImg* const img, QObject* const parent) | |||
49 | : DImgThreadedAnalyser(parent, QLatin1String("AutoCrop")), | |||
50 | d (new Private) | |||
51 | { | |||
52 | setOriginalImage(*img); | |||
53 | } | |||
54 | ||||
55 | AutoCrop::~AutoCrop() | |||
56 | { | |||
57 | delete d; | |||
58 | } | |||
59 | ||||
60 | QRect AutoCrop::spiralClockwiseTraversal(const QImage& source, int topCrop, int bottomCrop) | |||
61 | { | |||
62 | int i, j, ni; | |||
63 | ||||
64 | if (topCrop == -1) | |||
65 | { | |||
66 | topCrop = 0; | |||
67 | } | |||
68 | ||||
69 | if (bottomCrop == -1) | |||
70 | { | |||
71 | bottomCrop = source.height(); | |||
72 | } | |||
73 | ||||
74 | QSize resultsize = QSize(source.width(), (source.height() - topCrop - (source.height() - bottomCrop))); | |||
75 | QImage threshold = QImage(resultsize, QImage::Format_RGB888); | |||
76 | ||||
77 | for (i = topCrop, ni = 0 ; i < bottomCrop ; ++i, ++ni) | |||
78 | { | |||
79 | for (j = 0 ; j < source.width() ; ++j) | |||
80 | { | |||
81 | threshold.setPixel(j, ni, source.pixel(j, i)); | |||
82 | } | |||
83 | } | |||
84 | ||||
85 | QColor c; | |||
86 | int limitcolumn = threshold.width(); | |||
87 | int limitrow = threshold.height(); | |||
88 | int centeri = ((limitrow/2)-1); | |||
89 | int centerj = ((limitcolumn/2)-1); | |||
90 | int startrighti = 0; | |||
91 | int startrightj = 0; | |||
92 | int endrighti = 0; | |||
93 | int endrightj = 0; | |||
94 | int startlefti = 0; | |||
95 | int startleftj = 0; | |||
96 | int endlefti = 0; | |||
97 | int endleftj = 0; | |||
98 | int startupi = 0; | |||
99 | int startupj = 0; | |||
100 | int endupi = 0; | |||
101 | int endupj = 0; | |||
102 | int startdowni = 0; | |||
103 | int startdownj = 0; | |||
104 | int enddowni = 0; | |||
105 | int enddownj = 0; | |||
106 | int travelright = 0; | |||
107 | int travelleft = 0; | |||
108 | int travelup = 0; | |||
109 | int traveldown = 0; | |||
110 | int rightmargin = 0; | |||
111 | int leftmargin = 0; | |||
112 | int bottommargin = 0; | |||
113 | int topmargin = 0; | |||
114 | int counter = 0; | |||
115 | bool fixtopmargin = false; | |||
116 | bool fixrightmargin = false; | |||
117 | bool fixleftmargin = false; | |||
118 | bool fixbottommargin = false; | |||
119 | /* | |||
120 | int count = limitcolumn + limitrow -1; | |||
121 | */ | |||
122 | bool rightEdge = false; | |||
123 | bool leftEdge = false; | |||
124 | bool topEdge = false; | |||
125 | bool bottomEdge = false; | |||
126 | ||||
127 | endupi = centeri; | |||
128 | endupj = centerj; | |||
129 | travelright = -1; | |||
130 | traveldown = -1; | |||
131 | travelleft = 0; | |||
132 | travelup = 0; | |||
133 | ||||
134 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 134, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Center pixel : " << centerj << " , " << centeri; | |||
135 | ||||
136 | while (true) | |||
137 | { | |||
138 | //qCDebug(DIGIKAM_DIMG_LOG) << "count = "<<count; | |||
139 | ||||
140 | switch (counter % 4) | |||
141 | { | |||
142 | case 0: // traveling right | |||
143 | { | |||
144 | if (fixtopmargin == true) | |||
145 | { | |||
146 | if (fixrightmargin == false) | |||
147 | { | |||
148 | endrightj++; | |||
149 | ||||
150 | if (endrightj >= threshold.width()) | |||
151 | { | |||
152 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 152, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "We cannot go right anymore"; | |||
153 | fixrightmargin = true; | |||
154 | rightmargin = limitcolumn - 1; | |||
155 | rightEdge = true; | |||
156 | } | |||
157 | } | |||
158 | ||||
159 | break; | |||
160 | } | |||
161 | ||||
162 | travelright += 2; | |||
163 | ||||
164 | if (fixrightmargin == true) | |||
165 | { | |||
166 | travelright--; | |||
167 | } | |||
168 | ||||
169 | if (fixleftmargin == true) | |||
170 | { | |||
171 | travelright--; | |||
172 | } | |||
173 | ||||
174 | //qCDebug(DIGIKAM_DIMG_LOG) << "TRAVELING RIGHT"; | |||
175 | //qCDebug(DIGIKAM_DIMG_LOG) << "Endupi" << endupi; | |||
176 | startrighti = endupi; | |||
177 | startrightj = endupj; | |||
178 | endrightj = startrightj + travelright; | |||
179 | //qCDebug(DIGIKAM_DIMG_LOG) << "Moving Right EndRight = " << endrightj; | |||
180 | ||||
181 | if (endrightj >= limitcolumn) | |||
182 | { | |||
183 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 183, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "We have reached limitcolumn, i.e. width"; | |||
184 | endrightj = limitcolumn - 1; | |||
185 | fixrightmargin = true; | |||
186 | rightmargin = limitcolumn - 1; | |||
187 | counter++; | |||
188 | travelright--; | |||
189 | rightEdge = true; | |||
190 | } | |||
191 | ||||
192 | i = startrighti; | |||
193 | j = startrightj; | |||
194 | (void)j; // Remove clang warnings. | |||
195 | ||||
196 | for (j = startrightj + 1 ; j <= endrightj ; ++j) | |||
197 | { | |||
198 | //qCDebug(DIGIKAM_DIMG_LOG) << "At pixel "<< j << " , " << i; | |||
199 | c = QColor::fromRgb(threshold.pixel(j,i)); | |||
200 | ||||
201 | if (c == Qt::black) | |||
202 | { | |||
203 | // we have found an empty space | |||
204 | ||||
205 | fixtopmargin = true; | |||
206 | topmargin = i; | |||
207 | endupi++; | |||
208 | travelup--; | |||
209 | break; | |||
210 | } | |||
211 | } | |||
212 | ||||
213 | endrighti = startrighti; | |||
214 | ||||
215 | break; | |||
216 | } | |||
217 | ||||
218 | case 1: // traveling down | |||
219 | { | |||
220 | if (fixrightmargin == true) | |||
221 | { | |||
222 | if (fixbottommargin == false) | |||
223 | { | |||
224 | enddowni++; | |||
225 | ||||
226 | if (enddowni >= limitrow) | |||
227 | { | |||
228 | fixbottommargin = true; | |||
229 | bottommargin = limitrow - 1; | |||
230 | bottomEdge = true; | |||
231 | } | |||
232 | } | |||
233 | ||||
234 | //endrightj--; | |||
235 | //qCDebug(DIGIKAM_DIMG_LOG) << "Traveling down : Case Skipped\n"; | |||
236 | break; | |||
237 | } | |||
238 | ||||
239 | traveldown += 2; | |||
240 | ||||
241 | if (fixbottommargin == true) | |||
242 | { | |||
243 | traveldown--; | |||
244 | } | |||
245 | ||||
246 | if (fixtopmargin == true) | |||
247 | { | |||
248 | traveldown--; | |||
249 | } | |||
250 | ||||
251 | startdowni = endrighti; | |||
252 | startdownj = endrightj; | |||
253 | enddowni = startdowni + traveldown; | |||
254 | //qCDebug(DIGIKAM_DIMG_LOG) << "Moving Down EndDown = " << enddowni; | |||
255 | ||||
256 | if (enddowni >= limitrow) | |||
257 | { | |||
258 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 258, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "We have reached limitrow, i.e. Height"; | |||
259 | enddowni = limitrow - 1; | |||
260 | counter++; | |||
261 | bottommargin = limitrow - 1; | |||
262 | fixbottommargin = true; | |||
263 | traveldown--; | |||
264 | bottomEdge = true; | |||
265 | } | |||
266 | ||||
267 | i = startdowni; | |||
268 | (void)i; // Remove clang warning. | |||
269 | j = startdownj; | |||
270 | ||||
271 | for (i = startdowni + 1 ; i <= enddowni ; ++i) | |||
272 | { | |||
273 | // qCDebug(DIGIKAM_DIMG_LOG) << "At pixel "<< j << " , " << i; | |||
274 | c = QColor::fromRgb(threshold.pixel(j,i)); | |||
275 | ||||
276 | if (c == Qt::black) | |||
277 | { | |||
278 | //we have found an empty space | |||
279 | ||||
280 | fixrightmargin = true; | |||
281 | rightmargin = j; | |||
282 | endrightj--; | |||
283 | travelright--; | |||
284 | break; | |||
285 | } | |||
286 | } | |||
287 | ||||
288 | enddownj = startdownj; | |||
289 | ||||
290 | break; | |||
291 | } | |||
292 | case 2 : //traveling left | |||
293 | { | |||
294 | if (fixbottommargin == true) | |||
295 | { | |||
296 | if (fixleftmargin == false) | |||
297 | { | |||
298 | endleftj--; | |||
299 | ||||
300 | if (endleftj < 0) | |||
301 | { | |||
302 | fixleftmargin = true; | |||
303 | leftmargin = 0; | |||
304 | leftEdge = true; | |||
305 | } | |||
306 | } | |||
307 | ||||
308 | break; | |||
309 | } | |||
310 | ||||
311 | travelleft += 2; | |||
312 | ||||
313 | if (fixleftmargin == true) | |||
314 | { | |||
315 | travelleft--; | |||
316 | } | |||
317 | ||||
318 | if (fixrightmargin == true) | |||
319 | { | |||
320 | travelleft--; | |||
321 | } | |||
322 | ||||
323 | startlefti = enddowni; | |||
324 | startleftj = enddownj; | |||
325 | endleftj = startleftj - travelleft; | |||
326 | //qCDebug(DIGIKAM_DIMG_LOG) << "Moving Left Endleft = " << endleftj; | |||
327 | ||||
328 | if (endleftj < 0) | |||
329 | { | |||
330 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 330, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "We have gone too left"; | |||
331 | endleftj = 0; | |||
332 | counter++; | |||
333 | leftmargin = 0; | |||
334 | fixleftmargin = true; | |||
335 | travelleft--; | |||
336 | leftEdge = true; | |||
337 | } | |||
338 | ||||
339 | i = startlefti; | |||
340 | j = startleftj; | |||
341 | (void)j; // Remove clang warning. | |||
342 | ||||
343 | for (j = startleftj - 1 ; j >= endleftj ; --j) | |||
344 | { | |||
345 | //qCDebug(DIGIKAM_DIMG_LOG) << "At pixel "<< j << " , " << i; | |||
346 | c = QColor::fromRgb(threshold.pixel(j,i)); | |||
347 | ||||
348 | if (c == Qt::black) | |||
349 | { | |||
350 | // we have found an empty space | |||
351 | ||||
352 | fixbottommargin = true; | |||
353 | bottommargin = i; | |||
354 | enddowni--; | |||
355 | traveldown--; | |||
356 | break; | |||
357 | } | |||
358 | } | |||
359 | ||||
360 | endlefti = startlefti; | |||
361 | ||||
362 | break; | |||
363 | } | |||
364 | ||||
365 | case 3: //traveling up | |||
366 | { | |||
367 | if (fixleftmargin == true) | |||
368 | { | |||
369 | if (fixtopmargin == false) | |||
370 | { | |||
371 | endupi--; | |||
372 | endupj = leftmargin; | |||
373 | ||||
374 | if (endupi < 0) | |||
375 | { | |||
376 | fixtopmargin = true; | |||
377 | topmargin = 0; | |||
378 | topEdge = true; | |||
379 | } | |||
380 | } | |||
381 | ||||
382 | break; | |||
383 | } | |||
384 | ||||
385 | travelup += 2; | |||
386 | ||||
387 | if (fixbottommargin == true) | |||
388 | { | |||
389 | travelup--; | |||
390 | } | |||
391 | ||||
392 | if (fixtopmargin == true) | |||
393 | { | |||
394 | travelup--; | |||
395 | } | |||
396 | ||||
397 | startupi = endlefti; | |||
398 | startupj = endleftj; | |||
399 | endupi = startupi - travelup; | |||
400 | //qCDebug(DIGIKAM_DIMG_LOG) << "Moving Up Endup = " << endupi; | |||
401 | ||||
402 | if (endupi < 0) | |||
403 | { | |||
404 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 404, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "We have gone too right"; | |||
405 | endupi = 0; | |||
406 | topEdge = true; | |||
407 | counter++; | |||
408 | fixtopmargin = true; | |||
409 | topmargin = 0; | |||
410 | travelup--; | |||
411 | } | |||
412 | ||||
413 | i = startupi; | |||
414 | (void)i; // Remove clang warning. | |||
415 | j = startupj; | |||
416 | ||||
417 | for (i = startupi - 1 ; i >= endupi ; --i) | |||
418 | { | |||
419 | //qCDebug(DIGIKAM_DIMG_LOG) << "At pixel "<< j << " , " << i; | |||
420 | c = QColor::fromRgb(threshold.pixel(j, i)); | |||
421 | ||||
422 | if (c == Qt::black) | |||
423 | { | |||
424 | // we have found an empty space | |||
425 | ||||
426 | fixleftmargin = true; | |||
427 | leftmargin = j; | |||
428 | endleftj++; | |||
429 | travelleft--; | |||
430 | break; | |||
431 | } | |||
432 | } | |||
433 | ||||
434 | endupj = startupj; | |||
435 | ||||
436 | break; | |||
437 | } | |||
438 | } | |||
439 | ||||
440 | counter++; | |||
441 | ||||
442 | if ( | |||
443 | (fixbottommargin == true) && | |||
444 | (fixtopmargin == true) && | |||
445 | (fixleftmargin == true) && | |||
446 | (fixrightmargin == true) | |||
447 | ) | |||
448 | { | |||
449 | break; | |||
450 | } | |||
451 | } | |||
452 | ||||
453 | // qCDebug(DIGIKAM_DIMG_LOG) << "Count : " << count; | |||
454 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 454, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Endupi : " << endupi; | |||
455 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 455, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Endupj : " << endupj; | |||
456 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 456, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Endrighti : " << endrighti; | |||
457 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 457, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Endrightj : " << endrightj; | |||
458 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 458, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Enddowni : " << enddowni; | |||
459 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 459, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Enddownj : " << enddownj; | |||
460 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 460, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Endlefti : " << endlefti; | |||
461 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 461, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Endleftj : " << endleftj; | |||
462 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 462, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Done" << Qt::endl; | |||
463 | ||||
464 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 464, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Left Margin : " << leftmargin; | |||
465 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 465, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Right Margin : " << rightmargin; | |||
466 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 466, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Top Margin : " << topmargin; | |||
467 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 467, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Bottom Margin : " << bottommargin; | |||
468 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 468, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Done" << Qt::endl; | |||
469 | ||||
470 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 470, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Left Edge : " << leftEdge; | |||
471 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 471, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Right Edge : " << rightEdge; | |||
472 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 472, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Top Edge : " << topEdge; | |||
473 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 473, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Bottom Edge : " << bottomEdge; | |||
474 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 474, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Done" << Qt::endl; | |||
475 | ||||
476 | if (bottomEdge) | |||
477 | { | |||
478 | bottommargin++; | |||
479 | } | |||
480 | ||||
481 | if (topEdge) | |||
482 | { | |||
483 | topmargin--; | |||
484 | } | |||
485 | ||||
486 | if (leftEdge) | |||
487 | { | |||
488 | leftmargin--; | |||
489 | } | |||
490 | ||||
491 | if (rightEdge) | |||
492 | { | |||
493 | rightmargin++; | |||
494 | } | |||
495 | ||||
496 | //----------------------releasing images | |||
497 | ||||
498 | QPoint icp1; | |||
499 | icp1.setX(leftmargin + 1); | |||
500 | icp1.setY(topCrop + topmargin + 1); | |||
501 | QPoint icp2; | |||
502 | icp2.setX(rightmargin - 1); | |||
503 | icp2.setY(topCrop + bottommargin - 1); | |||
504 | QRect cropArea; | |||
505 | cropArea.setTopLeft(icp1); | |||
506 | cropArea.setBottomRight(icp2); | |||
507 | ||||
508 | return cropArea; | |||
509 | } | |||
510 | ||||
511 | void AutoCrop::startAnalyse() | |||
512 | { | |||
513 | QImage img = m_orgImage.copyQImage(); | |||
514 | int breakflag = 0; | |||
515 | int topRow = -1; | |||
516 | int topColumn = -1; | |||
517 | int bottomRow = -1; | |||
518 | int bottomColumn = -1; | |||
519 | int leftRow = -1; | |||
520 | int leftColumn = -1; | |||
521 | int rightRow = -1; | |||
522 | int rightColumn = -1; | |||
523 | QColor c; | |||
524 | int i, j; | |||
525 | ||||
526 | postProgress(5); | |||
527 | ||||
528 | //---------------------- Finding the outer boundaries of the image (i.e. with black portions) | |||
529 | ||||
530 | /** | |||
531 | * This would be done in 4 steps | |||
532 | * 1. Search column wise: | |||
533 | * (a) From the left to the right, this is to get the left boundary | |||
534 | * (b) From the right to the left, this is to get the right boundary | |||
535 | * 2. Search row wise : | |||
536 | * (a) From the top to the bottom, this is to get the top boundary | |||
537 | * (b) From the bottom to the top, this is to get the bottom boundary | |||
538 | */ | |||
539 | ||||
540 | // 1(a) Traversing the image from top to bottom, left to right, to get left boundary | |||
541 | ||||
542 | breakflag = 0; | |||
543 | int width = img.width(); | |||
544 | int height = img.height(); | |||
545 | ||||
546 | for (i = 0 ; i < width ; ++i) | |||
| ||||
547 | { | |||
548 | for (j = 0 ; j < height ; ++j) | |||
549 | { | |||
550 | c = QColor::fromRgb(img.pixel(i, j)); | |||
551 | ||||
552 | if ((c == Qt::black) || !c.isValid()) | |||
553 | { | |||
554 | // Nothing to do. | |||
555 | } | |||
556 | else | |||
557 | { | |||
558 | //we have found our pixel | |||
559 | leftRow = j; | |||
560 | leftColumn = i; | |||
561 | breakflag = 1; | |||
562 | break; | |||
563 | } | |||
564 | } | |||
565 | ||||
566 | if (breakflag
| |||
567 | { | |||
568 | break; | |||
569 | } | |||
570 | } | |||
571 | ||||
572 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 572, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Done Till step 1(a)"; | |||
573 | postProgress(30); | |||
574 | ||||
575 | //1(b) Traversing the image from top to bottom, right to left, to get right boundary | |||
576 | ||||
577 | breakflag = 0; | |||
578 | (void)breakflag; // Remove clang warnings. | |||
579 | ||||
580 | for (i = 0 ; i < width ; ++i) | |||
581 | { | |||
582 | for (j = 0 ; j
| |||
583 | { | |||
584 | c = QColor::fromRgb(img.pixel(i, j)); | |||
585 | ||||
586 | if ((c == Qt::black) || !c.isValid()) | |||
587 | { | |||
588 | // Nothing to do. | |||
589 | } | |||
590 | else | |||
591 | { | |||
592 | // we have found our pixel | |||
593 | ||||
594 | rightRow = j; | |||
595 | rightColumn = i; | |||
596 | break; | |||
597 | } | |||
598 | } | |||
599 | } | |||
600 | ||||
601 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 601, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Done Till step 1(b)"; | |||
602 | postProgress(50); | |||
603 | ||||
604 | // 2(a) Traversing the image left to right, top to down, to get top boundary | |||
605 | ||||
606 | breakflag = 0; | |||
607 | ||||
608 | for (i = 0 ; i
| |||
609 | { | |||
610 | for (j = 0 ; j < width ; ++j) | |||
611 | { | |||
612 | c = QColor::fromRgb(img.pixel(j, i)); | |||
613 | ||||
614 | if ((c == Qt::black) || !c.isValid()) | |||
615 | { | |||
616 | // Nothing to do. | |||
617 | } | |||
618 | else | |||
619 | { | |||
620 | // we have found our pixel | |||
621 | ||||
622 | topRow = i; | |||
623 | topColumn = j; | |||
624 | breakflag = 1; | |||
625 | break; | |||
626 | } | |||
627 | } | |||
628 | ||||
629 | if (breakflag == 1) | |||
630 | { | |||
631 | break; | |||
632 | } | |||
633 | } | |||
634 | ||||
635 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 635, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Done Till step 2(a)"; | |||
636 | postProgress(70); | |||
637 | ||||
638 | // 2(b) Traversing the image from left to right, bottom up, to get lower boundary | |||
639 | ||||
640 | breakflag = 0; | |||
641 | ||||
642 | for (i = height - 1 ; i >= 0 ; --i) | |||
643 | { | |||
644 | for (j = 0 ; j < width ; ++j) | |||
645 | { | |||
646 | c = QColor::fromRgb(img.pixel(j,i)); | |||
647 | ||||
648 | if ((c == Qt::black) || !c.isValid()) | |||
649 | { | |||
650 | // Nothing to do. | |||
651 | } | |||
652 | else | |||
653 | { | |||
654 | // we have found our pixel | |||
655 | ||||
656 | bottomRow = i; | |||
657 | bottomColumn = j; | |||
658 | breakflag = 1; | |||
659 | break; | |||
660 | } | |||
661 | } | |||
662 | ||||
663 | if (breakflag == 1) | |||
664 | { | |||
665 | break; | |||
666 | } | |||
667 | } | |||
668 | ||||
669 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 669, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Done Till step 2(b)"; | |||
670 | postProgress(90); | |||
671 | ||||
672 | //------making the required output-------------------- | |||
673 | ||||
674 | QString outercropParameters; | |||
675 | outercropParameters.append(QLatin1String("TopMost Pixel : ( ")); | |||
676 | outercropParameters.append(QString::number(topRow)); | |||
677 | outercropParameters.append(QLatin1String(", ")); | |||
678 | outercropParameters.append(QString::number(topColumn)); | |||
679 | outercropParameters.append(QLatin1String(")\nBottomMost Pixel : ( ")); | |||
680 | outercropParameters.append(QString::number(bottomRow)); | |||
681 | outercropParameters.append(QLatin1String(", ")); | |||
682 | outercropParameters.append(QString::number(bottomColumn)); | |||
683 | outercropParameters.append(QLatin1String(")\nLeftMost Pixel : ( ")); | |||
684 | outercropParameters.append(QString::number(leftRow)); | |||
685 | outercropParameters.append(QLatin1String(", ")); | |||
686 | outercropParameters.append(QString::number(leftColumn)); | |||
687 | outercropParameters.append(QLatin1String(")\nRightMost Pixel : ( ")); | |||
688 | outercropParameters.append(QString::number(rightRow)); | |||
689 | outercropParameters.append(QLatin1String(", ")); | |||
690 | outercropParameters.append(QString::number(rightColumn)); | |||
691 | outercropParameters.append(QLatin1String(")\nDONE")); | |||
692 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 692, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << outercropParameters; | |||
693 | postProgress(91); | |||
694 | ||||
695 | QPoint p1; | |||
696 | p1.setX(leftColumn); | |||
697 | p1.setY(topRow); | |||
698 | QPoint p2; | |||
699 | p2.setX(rightColumn); | |||
700 | p2.setY(bottomRow); | |||
701 | QRect crop; | |||
702 | crop.setTopLeft(p1); | |||
703 | crop.setBottomRight(p2); | |||
704 | ||||
705 | // crop Image to outerCrop | |||
706 | ||||
707 | QImage result; | |||
708 | QSize resultsize = QSize(crop.width(), crop.height()); | |||
709 | result = QImage(resultsize, QImage::Format_RGB888); | |||
710 | int ni, nj; | |||
711 | ||||
712 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 712, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Outer Crop area:"; | |||
713 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 713, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "From "<< crop.top() << " to " << crop.bottom() | |||
714 | << " & " << crop.left() << " to " << crop.right(); | |||
715 | ||||
716 | for (i = crop.top(), ni = 0 ; i <= crop.bottom() ; ++i, ++ni) | |||
717 | { | |||
718 | for (j = crop.left(), nj = 0 ; j <= crop.right() ; ++j, ++nj) | |||
719 | { | |||
720 | result.setPixel(nj, ni, img.pixel(j, i)); | |||
721 | } | |||
722 | } | |||
723 | ||||
724 | //---------------------threshold the image | |||
725 | ||||
726 | QImage threshold = QImage(resultsize,QImage::Format_RGB888); | |||
727 | int toggleflag1 = 0,toggleflag2 = 0; | |||
728 | int whitepixelCount = 0; | |||
729 | ||||
730 | //-----initialize | |||
731 | ||||
732 | for (i = 0 ; i < result.height() ; ++i) | |||
733 | { | |||
734 | for (j = 0 ; j < result.width() ; ++j) | |||
735 | { | |||
736 | threshold.setPixel(j, i, Qt::black); | |||
737 | } | |||
738 | } | |||
739 | ||||
740 | //----------mark points on horizontal scan | |||
741 | ||||
742 | for (i = 0 ; i < result.height() ; ++i) | |||
743 | { | |||
744 | toggleflag1 = -1; | |||
745 | toggleflag2 = -1; | |||
746 | ||||
747 | for (j = 0 ; j < result.width() ; ++j) | |||
748 | { | |||
749 | c = QColor::fromRgb(result.pixel(j, i)); | |||
750 | ||||
751 | if (c != Qt::black) | |||
752 | { | |||
753 | toggleflag1 = j; | |||
754 | break; | |||
755 | } | |||
756 | } | |||
757 | ||||
758 | for (j = (result.width()-1) ; j >= 0 ; --j) | |||
759 | { | |||
760 | c = QColor::fromRgb(result.pixel(j, i)); | |||
761 | ||||
762 | if (c != Qt::black) | |||
763 | { | |||
764 | toggleflag2 = j; | |||
765 | break; | |||
766 | } | |||
767 | } | |||
768 | ||||
769 | if (toggleflag1 >= 0) | |||
770 | { | |||
771 | for (j = toggleflag1 ; j <= toggleflag2 ; ++j) | |||
772 | { | |||
773 | threshold.setPixel(j, i, qRgb(255, 255, 255)); | |||
774 | } | |||
775 | } | |||
776 | } | |||
777 | ||||
778 | //----------fill black points on vertical scan | |||
779 | ||||
780 | for (j = 0 ; j < result.width() ; ++j) | |||
781 | { | |||
782 | toggleflag1 = -1; | |||
783 | toggleflag2 = -2; | |||
784 | ||||
785 | for (i = 0 ; i < result.height() ; ++i) | |||
786 | { | |||
787 | c = QColor::fromRgb(result.pixel(j, i)); | |||
788 | ||||
789 | if (c != Qt::black) | |||
790 | { | |||
791 | toggleflag1 = i; | |||
792 | break; | |||
793 | } | |||
794 | } | |||
795 | ||||
796 | for (i = (result.height()-1) ; i >= 0 ; --i) | |||
797 | { | |||
798 | c = QColor::fromRgb(result.pixel(j, i)); | |||
799 | ||||
800 | if (c != Qt::black) | |||
801 | { | |||
802 | toggleflag2 = i; | |||
803 | break; | |||
804 | } | |||
805 | } | |||
806 | ||||
807 | if (toggleflag1 >= 0) | |||
808 | { | |||
809 | for (i = 0 ; i < toggleflag1 ; ++i) | |||
810 | { | |||
811 | threshold.setPixel(j, i, qRgb(0, 0, 0)); | |||
812 | } | |||
813 | } | |||
814 | ||||
815 | if (toggleflag2 >= 0) | |||
816 | { | |||
817 | for (i = (toggleflag2+1) ; i < (result.height()) ; ++i) | |||
818 | { | |||
819 | threshold.setPixel(j, i, qRgb(0, 0, 0)); | |||
820 | } | |||
821 | } | |||
822 | } | |||
823 | ||||
824 | // ---count of white pixel in threshold | |||
825 | ||||
826 | for (i = 0 ; i < threshold.height() ; ++i) | |||
827 | { | |||
828 | for (j = 0 ; j < threshold.width() ; ++j) | |||
829 | { | |||
830 | c = QColor::fromRgb(threshold.pixel(j, i)); | |||
831 | ||||
832 | if (c == Qt::white) | |||
833 | { | |||
834 | whitepixelCount++; | |||
835 | } | |||
836 | } | |||
837 | } | |||
838 | ||||
839 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 839, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "White pixel count in thresholded image = " << whitepixelCount; | |||
840 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 840, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Thresholding Complete\n"; | |||
841 | ||||
842 | //---------------------inner crop | |||
843 | ||||
844 | QRect InrCrop = spiralClockwiseTraversal(threshold,-1,-1); | |||
845 | QPoint icp1; | |||
846 | icp1.setX(InrCrop.topLeft().x() + leftColumn); | |||
847 | icp1.setY(InrCrop.topLeft().y() + topRow); | |||
848 | QPoint icp2; | |||
849 | icp2.setX(InrCrop.bottomRight().x() + leftColumn); | |||
850 | icp2.setY(InrCrop.bottomRight().y() + topRow); | |||
851 | QRect cropArea; | |||
852 | cropArea.setTopLeft(icp1); | |||
853 | cropArea.setBottomRight(icp2); | |||
854 | ||||
855 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 855, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "cropArea : "<<cropArea; | |||
856 | ||||
857 | // Step 1. check for extra small crop | |||
858 | // Step 2. Find out first minima from left and right, crop accordingly | |||
859 | ||||
860 | //-----Step 1 -- Check for extra small crop | |||
861 | ||||
862 | int area = cropArea.height() * cropArea.width(); | |||
863 | ||||
864 | if (area > (whitepixelCount / 1.43)) | |||
865 | { | |||
866 | d->cropArea.setTopLeft(icp1); | |||
867 | d->cropArea.setBottomRight(icp2); | |||
868 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 868, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Inner Crop Area : " << d->cropArea; | |||
869 | return; | |||
870 | } | |||
871 | else | |||
872 | { | |||
873 | //threshold.save("ThresholdedImage.jpg",0,100); | |||
874 | ||||
875 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 875, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Area not adequate!"; | |||
876 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 876, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Extra Cropping Required"; | |||
877 | ||||
878 | // --- Step 2 -- Search between local minima | |||
879 | ||||
880 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 880, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "In local minima function"; | |||
881 | ||||
882 | // We need to find the maxima between the first two local minima from either side | |||
883 | ||||
884 | int* const blackpointCount = new int[threshold.width()]{}; | |||
885 | int leftminima = 0; | |||
886 | int rightminima = (threshold.width()-1); | |||
887 | int topCropLine = 0; | |||
888 | int bottomCropLine = threshold.height()-1; | |||
889 | int temp; | |||
890 | int temppos; | |||
891 | int count; | |||
892 | ||||
893 | (void) bottomCropLine; // Remove clang warnings. | |||
894 | ||||
895 | // initialize black point count | |||
896 | ||||
897 | for (i = 0 ; i < threshold.width() ; ++i) | |||
898 | { | |||
899 | blackpointCount[i] = 0; | |||
900 | } | |||
901 | ||||
902 | for (j = 0 ; j < threshold.width() ; ++j) | |||
903 | { | |||
904 | count = 0; | |||
905 | ||||
906 | for (i = 0 ; i < threshold.height(); ++i) | |||
907 | { | |||
908 | c = QColor::fromRgb(threshold.pixel(j, i)); | |||
909 | ||||
910 | if (c == Qt::black) | |||
911 | { | |||
912 | count++; | |||
913 | } | |||
914 | else | |||
915 | { | |||
916 | break; | |||
917 | } | |||
918 | } | |||
919 | ||||
920 | blackpointCount[j] = count; | |||
921 | } | |||
922 | ||||
923 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 923, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Top black element count Data Entry Completed"; | |||
924 | ||||
925 | // --- Searching left minima | |||
926 | ||||
927 | for (j = 1 ; j < threshold.width() ; ++j) | |||
928 | { | |||
929 | if ((blackpointCount[j] > blackpointCount[j-1]) && | |||
| ||||
930 | (blackpointCount[j] < (0.2*threshold.height()))) | |||
931 | { | |||
932 | leftminima = j-1; | |||
933 | break; | |||
934 | } | |||
935 | } | |||
936 | ||||
937 | for (j = (threshold.width()-2) ; j >= 0 ; --j) | |||
938 | { | |||
939 | if ((blackpointCount[j] > blackpointCount[j+1]) && | |||
940 | (blackpointCount[j] < (0.2*threshold.height()))) | |||
941 | { | |||
942 | rightminima = j+1; | |||
943 | break; | |||
944 | } | |||
945 | } | |||
946 | ||||
947 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 947, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Top Part right minima : " << rightminima << " Left Minima : " << leftminima; | |||
948 | ||||
949 | // --- find the maximum among these minima | |||
950 | ||||
951 | temp = blackpointCount[leftminima]; | |||
952 | temppos = leftminima; | |||
953 | ||||
954 | for (j = leftminima+1 ; j <= rightminima ; ++j) | |||
955 | { | |||
956 | if (temp < blackpointCount[j]) | |||
957 | { | |||
958 | temp = blackpointCount[j]; | |||
959 | temppos = j; | |||
960 | } | |||
961 | } | |||
962 | ||||
963 | topCropLine = temp; | |||
964 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 964, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Found top crop line"; | |||
965 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 965, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Found in column = " << temppos << "and the topCropLine is "<< topCropLine; | |||
966 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 966, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Searching for bottom crop line"; | |||
967 | ||||
968 | //-----For the bottom of the image | |||
969 | ||||
970 | // initialize black point count | |||
971 | ||||
972 | for (i = 0 ; i < threshold.width() ; ++i) | |||
973 | { | |||
974 | blackpointCount[i] = 0; | |||
975 | } | |||
976 | ||||
977 | for (j = 0 ; j < threshold.width() ; ++j) | |||
978 | { | |||
979 | count = 0; | |||
980 | ||||
981 | for (i = (threshold.height()-1) ; i >= 0; --i) | |||
982 | { | |||
983 | c = QColor::fromRgb(result.pixel(j, i)); | |||
984 | ||||
985 | if (c == Qt::black) | |||
986 | { | |||
987 | count++; | |||
988 | } | |||
989 | else | |||
990 | { | |||
991 | break; | |||
992 | } | |||
993 | } | |||
994 | ||||
995 | blackpointCount[j] = count; | |||
996 | } | |||
997 | ||||
998 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 998, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category.name()).debug() << "Bottom black element count Data Entry Completed"; | |||
999 | ||||
1000 | // --- Searching left minima | |||
1001 | ||||
1002 | for (j = 1 ; j < threshold.width() ; ++j) | |||
1003 | { | |||
1004 | if ((blackpointCount[j] > blackpointCount[j-1]) && | |||
1005 | (blackpointCount[j] < (0.2*threshold.height()))) | |||
1006 | { | |||
1007 | leftminima = j-1; | |||
1008 | break; | |||
1009 | } | |||
1010 | } | |||
1011 | ||||
1012 | for (j = (threshold.width()-2) ; j >= 0 ; --j) | |||
1013 | { | |||
1014 | if ((blackpointCount[j] > blackpointCount[j+1]) && | |||
1015 | (blackpointCount[j] < (0.2*threshold.height()))) | |||
1016 | { | |||
1017 | rightminima = j+1; | |||
1018 | break; | |||
1019 | } | |||
1020 | } | |||
1021 | ||||
1022 | // --- find the maximum among these minima | |||
1023 | ||||
1024 | temp = blackpointCount[leftminima]; | |||
1025 | temppos = leftminima; | |||
1026 | ||||
1027 | for (j = leftminima+1 ; j <= rightminima ; ++j) | |||
1028 | { | |||
1029 | if (temp < blackpointCount[j]) | |||
1030 | { | |||
1031 | temp = blackpointCount[j]; | |||
1032 | temppos = j; | |||
1033 | } | |||
1034 | } | |||
1035 | ||||
1036 | bottomCropLine = temp; | |||
1037 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 1037, static_cast<const char *>(__PRETTY_FUNCTION__) , qt_category.name()).debug() << "Found top crop line"; | |||
1038 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 1038, static_cast<const char *>(__PRETTY_FUNCTION__) , qt_category.name()).debug() << "Found in column = " << temppos; | |||
1039 | QRect newCrop = spiralClockwiseTraversal(threshold, topCropLine, (threshold.height()-bottomCropLine)); | |||
1040 | ||||
1041 | if (newCrop != crop) | |||
1042 | { | |||
1043 | icp1.setX(newCrop.topLeft().x() + leftColumn); | |||
1044 | icp1.setY(newCrop.topLeft().y() + topRow); | |||
1045 | icp2.setX(newCrop.bottomRight().x() + leftColumn); | |||
1046 | icp2.setY(newCrop.bottomRight().y() + topRow); | |||
1047 | d->cropArea.setTopLeft(icp1); | |||
1048 | d->cropArea.setBottomRight(icp2); | |||
1049 | } | |||
1050 | ||||
1051 | delete [] blackpointCount; | |||
1052 | } | |||
1053 | ||||
1054 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 1054, static_cast<const char *>(__PRETTY_FUNCTION__) , qt_category.name()).debug() << "Inner Crop Area : " << cropArea; | |||
1055 | /* | |||
1056 | return(cropArea); | |||
1057 | resultsize = QSize (cropArea.width(), cropArea.height()); | |||
1058 | QImage ic = QImage(resultsize,img.format()); | |||
1059 | ||||
1060 | for (i = cropArea.top(), ni = 0 ; i <= cropArea.bottom() ; i++, ni++ ) | |||
1061 | { | |||
1062 | for (j = cropArea.left(), nj = 0 ; j <= cropArea.right() ; j++, nj++ ) | |||
1063 | { | |||
1064 | ic.setPixel(nj, ni, img.pixel(j, i)); | |||
1065 | } | |||
1066 | } | |||
1067 | ||||
1068 | qCDebug(DIGIKAM_DIMG_LOG) << "From "<<cropArea.top()<<" to "<<cropArea.bottom()<<" & "<<cropArea.left()<<" to "<<cropArea.right(); | |||
1069 | ||||
1070 | if (ic.save("InnerCrop.jpg",0,100)) | |||
1071 | { | |||
1072 | qCDebug(DIGIKAM_DIMG_LOG) << "Inner Crop Function Saves the day!"; | |||
1073 | } | |||
1074 | else | |||
1075 | { | |||
1076 | qCDebug(DIGIKAM_DIMG_LOG) << "Inner Crop Functions fails"; | |||
1077 | } | |||
1078 | */ | |||
1079 | qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category ((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false ) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/autocrop.cpp" ), 1079, static_cast<const char *>(__PRETTY_FUNCTION__) , qt_category.name()).debug() << "Inner Crop Area : " << d->cropArea; | |||
1080 | } | |||
1081 | ||||
1082 | QRect AutoCrop::autoInnerCrop() const | |||
1083 | { | |||
1084 | return d->cropArea; | |||
1085 | } | |||
1086 | ||||
1087 | } // namespace Digikam | |||
1088 | ||||
1089 | #include "moc_autocrop.cpp" |