1 /*
2 * This file is part of Converseen, an open-source batch image converter
3 * and resizer.
4 *
5 * (C) Francesco Mondello 2009 - 2021
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * Contact e-mail: Francesco Mondello <faster3ck@gmail.com>
21 *
22 */
23
24 #include <QMessageBox>
25 #include <QInputDialog>
26 #include <QFileInfo>
27 #include "converter.h"
28
Converter(QObject * parent)29 Converter::Converter(QObject *parent)
30 : QThread(parent)
31 {
32 reset();
33 connect(this, SIGNAL(finished()), this, SLOT(conversionCompleted()));
34 }
35
conversionCompleted()36 void Converter::conversionCompleted()
37 {
38 emit nextConversion(m_conv_status);
39 }
40
reset()41 void Converter::reset()
42 {
43 m_zoom = false;
44 m_density = false;
45 m_rotation = false;
46 m_flip = false;
47 }
48
~Converter()49 Converter::~Converter()
50 {
51
52 }
53
run()54 void Converter::run()
55 {
56 m_process_stopped = 0;
57 m_conv_status = 2; // Jumped
58
59 Image my_image;
60 QFileInfo fi(m_fileNameIn);
61
62 QString out = m_fileNameOut;
63
64 if (!m_overwrite) // modalità sovrascrittura
65 out = overwriteOldFileName(out);
66
67 if (!m_process_stopped) {
68 try {
69 my_image.quiet(true);
70 my_image.read(m_fileNameIn.toStdString());
71
72 if (m_zoom)
73 resize(my_image);
74 if (m_density)
75 changeDensity(my_image);
76 if (m_rotation)
77 rotate(my_image);
78 if (m_flip)
79 flip(my_image);
80
81 if (writeImage(my_image, m_format, m_quality, out))
82 m_conv_status = 1;
83 }
84 catch (Error& my_error) {
85 m_conv_status = -1;
86
87 QString err_status = tr("Error: %1").arg(QString::fromStdString(my_error.what()));
88 emit errorMessage(err_status);
89 }
90 catch( Magick::WarningCoder &warning )
91 {
92 m_conv_status = -1;
93
94 QString err_status = tr("Error: %1").arg(QString::fromStdString(warning.what()));
95 emit errorMessage(err_status);
96 }
97 catch( Magick::Warning &warning )
98 {
99 m_conv_status = -1;
100
101 QString err_status = tr("Error: %1").arg(QString::fromStdString(warning.what()));
102 emit errorMessage(err_status);
103 }
104 }
105 }
106
setInputPicture(QString fileName)107 void Converter::setInputPicture(QString fileName) //Name
108 {
109 m_fileNameIn = fileName;
110 }
111
setOutputPictureName(QString fileName)112 void Converter::setOutputPictureName(QString fileName)
113 {
114 m_fileNameOut = fileName;
115 }
116
setFormat(QString format)117 void Converter::setFormat(QString format)
118 {
119 m_format = format;
120 }
121
setQuality(int quality)122 void Converter::setQuality(int quality)
123 {
124 m_quality = quality;
125 }
126
setOutputDir(QString outputDir)127 void Converter::setOutputDir(QString outputDir)
128 {
129 m_outputDir = outputDir;
130 }
131
setResize(QString resizingStr)132 void Converter::setResize(QString resizingStr)
133 {
134 resizingString = resizingStr;
135 m_zoom = true;
136 }
137
setRotation(double deg)138 void Converter::setRotation(double deg)
139 {
140 m_rotation = true;
141 m_rotation_deg = deg;
142 }
143
rotate(Image & my_image)144 void Converter::rotate(Image &my_image)
145 {
146 my_image.rotate(m_rotation_deg);
147 }
148
setFlip(FlipOrientation orientation)149 void Converter::setFlip(FlipOrientation orientation)
150 {
151 m_flip = true;
152 m_orientation = orientation;
153 }
154
flip(Image & my_image)155 void Converter::flip(Image &my_image)
156 {
157 if (m_orientation == VERTICAL)
158 my_image.flip();
159 if (m_orientation == HORIZONTAL)
160 my_image.flop();
161 }
162
resize(Image & my_image)163 void Converter::resize(Image &my_image)
164 {
165 my_image.filterType(m_resamplingFilter);
166 my_image.resize(resizingString.toStdString());
167 }
168
setDensity(QString densityStr)169 void Converter::setDensity(QString densityStr)
170 {
171 m_densityString = densityStr;
172 m_density = true;
173 }
174
changeDensity(Image & my_image)175 void Converter::changeDensity(Image &my_image)
176 {
177 QString n_den = QString(m_densityString);
178 my_image.resolutionUnits(PixelsPerInchResolution);
179 my_image.density(n_den.toStdString());
180 }
181
setBackgroundColor(QString bg_color,bool changeBg_color)182 void Converter::setBackgroundColor(QString bg_color, bool changeBg_color)
183 {
184 m_bg_color = bg_color;
185 m_changeBg_color = changeBg_color;
186 }
187
setOverwrite(bool overwrite)188 void Converter::setOverwrite(bool overwrite)
189 {
190 m_overwrite = overwrite;
191 }
192
overwriteOldFileName(QString out)193 QString Converter::overwriteOldFileName(QString out)
194 {
195 QFileInfo fi(out);
196 m_newBaseName = fi.baseName();
197
198 if (fi.exists()) {
199 if (!m_overwrite) {
200 emit requestOverwrite(m_newBaseName);
201
202 mutex.lock();
203 imageCondition.wait(&mutex);
204 mutex.unlock();
205 }
206 return QString("%1/%2.%3").arg(fi.path()).arg(m_newBaseName).arg(fi.suffix());
207 }
208 else
209 return out;
210 }
211
setNewBasename(QString newBaseName,bool ok)212 void Converter::setNewBasename(QString newBaseName, bool ok)
213 {
214 if (ok)
215 m_newBaseName = newBaseName;
216
217 imageCondition.wakeAll();
218 }
219
setResamplingFilter(IMFilterType resamplingFilter)220 void Converter::setResamplingFilter(IMFilterType resamplingFilter)
221 {
222 m_resamplingFilter = resamplingFilter;
223 }
224
writeImage(Image & my_image,QString format,int quality,QString out)225 bool Converter::writeImage(Image &my_image, QString format, int quality, QString out)
226 {
227 my_image.magick(format.toUpper().toStdString());
228
229 QStringList excludedFormats;
230 excludedFormats << "jpg" << "jpeg" << "bmp";
231
232 bool hasTransparency = false;
233
234 #if MagickLibVersion < 0x700
235 hasTransparency = my_image.matte();
236 #else
237 hasTransparency = my_image.alpha();
238 #endif
239
240 if (m_changeBg_color || (excludedFormats.contains(format, Qt::CaseInsensitive) && hasTransparency)) {
241 Image bgImg;
242 bgImg.size(Magick::Geometry(my_image.columns(), my_image.rows()));
243
244 bgImg.read("xc:" + m_bg_color.toStdString());
245 bgImg.label("bgImg");
246 bgImg.depth(my_image.depth());
247
248 bgImg.composite(my_image, Magick::Geometry(bgImg.columns(),bgImg.rows()), Magick::DissolveCompositeOp );
249
250 my_image = bgImg;
251 }
252
253 bool converted = false;
254
255 if (quality != -1)
256 my_image.quality(quality);
257
258 try {
259 my_image.write(out.toStdString());
260
261 converted = true;
262 }
263 catch (Error& my_error) {
264 converted = false;
265 }
266
267 return converted;
268 }
269
stopProcess()270 void Converter::stopProcess()
271 {
272 m_process_stopped = 1;
273 }
274