Line data Source code
1 : #include "ImageGrabber.h"
2 : #include "../network/BatchDownloadCore.h"
3 :
4 : #include <QMimeDatabase>
5 : #include <QtConcurrent>
6 :
7 55 : ImageGrabber::ImageGrabber(QObject *parent, QNetworkAccessManager* networkManager) :
8 : FangObject(parent),
9 55 : batchDownloader(new BatchDownloadCore(30000, 10, this, networkManager))
10 : {
11 55 : connect(batchDownloader, &BatchDownloadCore::finished,
12 55 : this, &ImageGrabber::onBatchFinished);
13 55 : connect(&processWatcher, &QFutureWatcher<void>::finished,
14 55 : this, &ImageGrabber::finished);
15 55 : }
16 :
17 16 : void ImageGrabber::fetchUrl(const QUrl &url)
18 : {
19 16 : QList<QUrl> urls;
20 16 : urls.append(url);
21 16 : fetchUrls(urls);
22 16 : }
23 :
24 31 : void ImageGrabber::fetchUrls(const QList<QUrl> &urls)
25 : {
26 31 : results.clear();
27 31 : batchDownloader->download(urls);
28 31 : }
29 :
30 31 : void ImageGrabber::onBatchFinished()
31 : {
32 : // Capture batch results on the main thread, then process on a background
33 : // thread to avoid blocking the UI during image decoding and MIME detection.
34 31 : QMap<QUrl, BatchDownloadResult> batchResults = batchDownloader->results();
35 :
36 : // Fast path: no images to process.
37 31 : if (batchResults.isEmpty()) {
38 1 : emit finished();
39 1 : return;
40 : }
41 :
42 60 : auto future = QtConcurrent::run([this, batchResults]() {
43 30 : QMimeDatabase mimeDb;
44 :
45 74 : for (auto it = batchResults.constBegin(); it != batchResults.constEnd(); ++it) {
46 44 : const QUrl& url = it.key();
47 44 : const BatchDownloadResult& batchResult = it.value();
48 :
49 44 : ImageData imageData;
50 :
51 44 : if (batchResult.success && !batchResult.data.isEmpty()) {
52 36 : QImage image = QImage::fromData(batchResult.data);
53 :
54 36 : if (!image.isNull()) {
55 35 : imageData.image = image;
56 35 : imageData.rawData = batchResult.data;
57 :
58 35 : QMimeType mimeType = mimeDb.mimeTypeForData(batchResult.data);
59 35 : imageData.mimeType = mimeType.name();
60 35 : }
61 36 : }
62 :
63 44 : results.insert(url, imageData);
64 44 : }
65 60 : });
66 30 : processWatcher.setFuture(future);
67 31 : }
|