Я хотел бы прочитать и отобразить уменьшенные версии фотографий с цифровых камер. В настоящее время я использую QImageReader, который имеет 2 функции, которые мне нужны, но они, кажется, взаимодействуют неоптимально ...:
Я хочу загрузить и отобразить изображение с шириной 100 пикселей после поворота на основе свойств EXIF. Однако, что происходит, это:
код:
QImageReader imageReader(filepath);
auto origSize1 = imageReader.size();
imageReader.setAutoTransform(true);
auto origSize2 = imageReader.size();
auto scaledSize1 = origSize1.scaled(QSize(100, 1000), Qt::KeepAspectRatio);
auto scaledSize2 = origSize2.scaled(QSize(100, 1000), Qt::KeepAspectRatio);
imageReader.setScaledSize(scaledSize2);
auto qimage = imageReader.read();
auto imageSize = qimage.size();
auto qimageScaled = qimage.scaledToWidth(100, Qt::SmoothTransformation);
auto scaledSize3 = qimageScaled.size();
std::cout << " origSize1 = (" << origSize1.width() << ", " << origSize1.height() << ")" << std::endl;
std::cout << " origSize2 = (" << origSize2.width() << ", " << origSize2.height() << ")" << std::endl;
std::cout << "scaledSize1 = (" << scaledSize1.width() << ", " << scaledSize1.height() << ")" << std::endl;
std::cout << "scaledSize2 = (" << scaledSize2.width() << ", " << scaledSize2.height() << ")" << std::endl;
std::cout << " imageSize = (" << imageSize.width() << ", " << imageSize.height() << ")" << std::endl;
std::cout << "scaledSize3 = (" << scaledSize3.width() << ", " << scaledSize3.height() << ")" << std::endl;
выход:
origSize1 = (4896, 3672)
origSize2 = (4896, 3672)
scaledSize1 = (100, 75)
scaledSize2 = (100, 75)
imageSize = (75, 100)
scaledSize3 = (100, 134)
Итак, изображение читается с шириной 100 пикселей в ландшафтном режиме, затем применяется автоповорот, в результате чего изображение в портретном режиме имеет ширину всего 75 пикселей и высоту 100 пикселей. Дополнительный вызов scaledToWidth () заботится о том, чтобы сделать изображение правильного размера, но качество очень плохое из-за масштабирования x1.34.
Кажется, я мог бы вызвать setScaledSize с двойным (или тройным, или ...) разрешением, которое мне нужно, чтобы получить достаточное качество, а затем полагаться на дополнительный вызов scaledToWidth (), чтобы получить правильную конечную ширину.
Лучшим подходом, по-видимому, является использование информации QImageReader :: translation () и ее использование для обмена шириной / высотой в объекте размера, переданном в setScaledSize:
пересмотренный код:
QImageReader imageReader(filepath);
auto origSize1 = imageReader.size();
imageReader.setAutoTransform(true);
auto transformation = imageReader.transformation();
auto swapWH = transformation.testFlag(QImageIOHandler::TransformationRotate90);
auto swappedSize = swapWH ? origSize1.transposed() : origSize1;
auto scaledSwappedSize = swappedSize.scaled(QSize(100, 1000), Qt::KeepAspectRatio);
imageReader.setScaledSize(scaledSwappedSize);
auto qimage = imageReader.read();
auto imageSize = qimage.size();
auto qimageScaled = qimage.scaledToWidth(100, Qt::SmoothTransformation);
auto scaledSize3 = qimageScaled.size();
вывод с этим исправленным кодом:
origSize1 = (4896, 3672)
transformation = 7
swap width/height? = 1
swappedSize = (3672, 4896)
scaledSwapp = (100, 133)
imageSize = (133, 100)
scaledSize3 = (100, 76)
Как вы можете видеть, я все равно получаю пейзажное изображение. Контент находится в портретном режиме, но растянут горизонтально (делая всех жирными). Итак, разрешение 100x133 в порядке, но мне нужно предоставить 133x100 для setScaledSize (), чтобы получить «нормальные» результаты:
QImageReader imageReader(filepath);
auto origSize1 = imageReader.size();
imageReader.setAutoTransform(true);
auto transformation = imageReader.transformation();
auto swapWH = transformation.testFlag(QImageIOHandler::TransformationRotate90);
auto swappedSize = swapWH ? origSize1.transposed() : origSize1;
auto scaledSwappedSize = swappedSize.scaled(QSize(100, 1000), Qt::KeepAspectRatio);
auto swappedScaledSwappedSize = swapWH ? scaledSwappedSize.transposed() : scaledSwappedSize;
imageReader.setScaledSize(swappedScaledSwappedSize);
auto qimage = imageReader.read();
auto imageSize = qimage.size();
auto qimageScaled = qimage.scaledToWidth(100, Qt::SmoothTransformation);
auto scaledSize3 = qimageScaled.size();
Теперь я получаю "правильные" результаты (обратите внимание, что imagesize == scaledSize3):
origSize1 = (4896, 3672)
transformation = 7
swap width/height? = 1
swappedSize = (3672, 4896)
scaledSwapp = (100, 133)
swpSclSwapp = (133, 100)
imageSize = (100, 133)
scaledSize3 = (100, 133)
Итак, я заставляю это работать, но я чувствую, что делаю слишком много циклического кода. Это ожидаемое поведение? Есть ли более простые способы получить этот результат?