File indexing completed on 2025-01-05 03:53:10
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2012-03-15 0007 * Description : a tool to create panorama by fusion of several images. 0008 * 0009 * SPDX-FileCopyrightText: 2012-2016 by Benjamin Girault <benjamin dot girault at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "createptotask.h" 0016 #include "ptotype.h" 0017 0018 // Qt includes 0019 0020 #include <QFile> 0021 0022 // KDE includes 0023 0024 #include <klocalizedstring.h> 0025 0026 namespace DigikamGenericPanoramaPlugin 0027 { 0028 0029 CreatePtoTask::CreatePtoTask(const QString& workDirPath, 0030 PanoramaFileType fileType, 0031 QUrl& ptoUrl, 0032 const QList<QUrl>& inputFiles, 0033 const PanoramaItemUrlsMap& preProcessedMap, 0034 bool addGPlusMetadata, 0035 const QString& huginVersion) 0036 : PanoTask(PANO_CREATEPTO, 0037 workDirPath), 0038 ptoUrl(ptoUrl), 0039 preProcessedMap(&preProcessedMap), 0040 fileType(addGPlusMetadata ? JPEG : fileType), 0041 inputFiles(inputFiles), 0042 addGPlusMetadata(addGPlusMetadata), 0043 huginVersion(huginVersion) 0044 { 0045 } 0046 0047 CreatePtoTask::~CreatePtoTask() 0048 { 0049 } 0050 0051 void CreatePtoTask::run(ThreadWeaver::JobPointer, ThreadWeaver::Thread*) 0052 { 0053 ptoUrl = tmpDir; 0054 ptoUrl.setPath(ptoUrl.path() + QLatin1String("pano_base.pto")); 0055 0056 QFile pto(ptoUrl.toLocalFile()); 0057 0058 if (pto.exists()) 0059 { 0060 errString = i18n("PTO file already created in the temporary directory."); 0061 successFlag = false; 0062 0063 return; 0064 } 0065 0066 if (!pto.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) 0067 { 0068 errString = i18n("PTO file cannot be created in the temporary directory."); 0069 successFlag = false; 0070 0071 return; 0072 } 0073 0074 pto.close(); 0075 0076 // 1. Project parameters 0077 0078 PTOType panoBase(huginVersion); 0079 0080 if (addGPlusMetadata) 0081 { 0082 panoBase.project.projection = PTOType::Project::EQUIRECTANGULAR; 0083 } 0084 else 0085 { 0086 panoBase.project.projection = PTOType::Project::CYLINDRICAL; 0087 } 0088 0089 panoBase.project.fieldOfView = 0; 0090 panoBase.project.hdr = false; 0091 0092 switch (fileType) 0093 { 0094 case JPEG: 0095 panoBase.project.fileFormat.fileType = PTOType::Project::FileFormat::JPEG; 0096 panoBase.project.fileFormat.quality = 90; 0097 break; 0098 0099 case TIFF: 0100 panoBase.project.fileFormat.fileType = PTOType::Project::FileFormat::TIFF_m; 0101 panoBase.project.fileFormat.compressionMethod = PTOType::Project::FileFormat::LZW; 0102 panoBase.project.fileFormat.savePositions = false; 0103 panoBase.project.fileFormat.cropped = false; 0104 break; 0105 0106 case HDR: 0107 panoBase.project.hdr = true; 0108 // TODO HDR 0109 break; 0110 } 0111 /* 0112 panoBase.project.bitDepth = PTOType::Project::FLOAT; 0113 panoBase.project.crop.setLeft(X_left); 0114 panoBase.project.crop.setRight(X_right); 0115 panoBase.project.crop.setTop(X_top); 0116 panoBase.project.crop.setBottom(X_bottom); 0117 */ 0118 panoBase.project.photometricReferenceId = 0; 0119 0120 // 2. Images 0121 0122 panoBase.images.reserve(inputFiles.size()); 0123 panoBase.images.resize(inputFiles.size()); 0124 int i = 0; 0125 0126 for (i = 0 ; i < inputFiles.size() ; ++i) 0127 { 0128 QUrl inputFile(inputFiles.at(i)); 0129 QUrl preprocessedUrl(preProcessedMap->value(inputFile).preprocessedUrl); 0130 m_meta.load(preprocessedUrl.toLocalFile()); 0131 QSize size = m_meta.getPixelSize(); 0132 0133 panoBase.images[i] = PTOType::Image(); 0134 panoBase.images[i].lensProjection = PTOType::Image::RECTILINEAR; 0135 panoBase.images[i].size = size; 0136 0137 if (i > 0) 0138 { 0139 // We suppose that the pictures are all taken with the same camera and lens 0140 0141 panoBase.images[i].lensBarrelCoefficientA.referenceId = 0; 0142 panoBase.images[i].lensBarrelCoefficientB.referenceId = 0; 0143 panoBase.images[i].lensBarrelCoefficientC.referenceId = 0; 0144 panoBase.images[i].lensCenterOffsetX.referenceId = 0; 0145 panoBase.images[i].lensCenterOffsetY.referenceId = 0; 0146 panoBase.images[i].lensShearX.referenceId = 0; 0147 panoBase.images[i].lensShearY.referenceId = 0; 0148 panoBase.images[i].vignettingCorrectionI.referenceId = 0; 0149 panoBase.images[i].vignettingCorrectionJ.referenceId = 0; 0150 panoBase.images[i].vignettingCorrectionK.referenceId = 0; 0151 panoBase.images[i].vignettingCorrectionL.referenceId = 0; 0152 panoBase.images[i].vignettingOffsetX.referenceId = 0; 0153 panoBase.images[i].vignettingOffsetY.referenceId = 0; 0154 } 0155 else 0156 { 0157 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0158 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::LENSA; 0159 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0160 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::LENSB; 0161 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0162 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::LENSC; 0163 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0164 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::LENSD; 0165 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0166 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::LENSE; 0167 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0168 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::VA; 0169 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0170 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::VB; 0171 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0172 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::VC; 0173 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0174 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::VD; 0175 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0176 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::VX; 0177 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0178 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::VY; 0179 } 0180 0181 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0182 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::RA; 0183 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0184 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::RB; 0185 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0186 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::RC; 0187 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0188 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::RD; 0189 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0190 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::RE; 0191 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0192 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::EXPOSURE; 0193 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0194 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::WBR; 0195 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0196 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::WBB; 0197 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0198 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::LENSYAW; 0199 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0200 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::LENSPITCH; 0201 panoBase.images[i].optimizationParameters.append(PTOType::Optimization()); 0202 panoBase.images[i].optimizationParameters.last().parameter = PTOType::Optimization::LENSROLL; 0203 panoBase.images[i].fileName = preprocessedUrl.toLocalFile(); 0204 } 0205 0206 switch (fileType) 0207 { 0208 case TIFF: 0209 panoBase.lastComments << QLatin1String("#hugin_outputImageType tif"); 0210 panoBase.lastComments << QLatin1String("#hugin_outputImageTypeCompression LZW"); 0211 break; 0212 0213 case JPEG: 0214 panoBase.lastComments << QLatin1String("#hugin_outputImageType jpg"); 0215 panoBase.lastComments << QLatin1String("#hugin_outputJPEGQuality 90"); 0216 break; 0217 0218 case HDR: 0219 // TODO: HDR 0220 break; 0221 } 0222 0223 panoBase.createFile(ptoUrl.toLocalFile()); 0224 0225 successFlag = true; 0226 } 0227 0228 } // namespace DigikamGenericPanoramaPlugin