|
|
|
@ -27,6 +27,8 @@
@@ -27,6 +27,8 @@
|
|
|
|
|
#include "src/widget/style.h" |
|
|
|
|
#include "src/widget/widget.h" |
|
|
|
|
|
|
|
|
|
#include <libexif/exif-loader.h> |
|
|
|
|
|
|
|
|
|
#include <QBuffer> |
|
|
|
|
#include <QDebug> |
|
|
|
|
#include <QDesktopServices> |
|
|
|
@ -528,7 +530,18 @@ void FileTransferWidget::showPreview(const QString& filename)
@@ -528,7 +530,18 @@ void FileTransferWidget::showPreview(const QString& filename)
|
|
|
|
|
// Subtract to make border visible
|
|
|
|
|
const int size = qMax(ui->previewButton->width(), ui->previewButton->height()) - 4; |
|
|
|
|
|
|
|
|
|
const QImage image = QImage(filename); |
|
|
|
|
QFile imageFile(filename); |
|
|
|
|
if (!imageFile.open(QIODevice::ReadOnly)) { |
|
|
|
|
qCritical() << "Failed to open file for preview"; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const QByteArray imageFileData = imageFile.readAll(); |
|
|
|
|
QImage image = QImage::fromData(imageFileData); |
|
|
|
|
const int exifOrientation = getExifOrientation(imageFileData.constData(), imageFileData.size()); |
|
|
|
|
if (exifOrientation) { |
|
|
|
|
applyTransformation(exifOrientation, image); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const QPixmap iconPixmap = scaleCropIntoSquare(QPixmap::fromImage(image), size); |
|
|
|
|
|
|
|
|
|
ui->previewButton->setIcon(QIcon(iconPixmap)); |
|
|
|
@ -585,3 +598,56 @@ QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int
@@ -585,3 +598,56 @@ QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int
|
|
|
|
|
// Picture was rectangle in the first place, no cropping
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int FileTransferWidget::getExifOrientation(const char* data, const int size) |
|
|
|
|
{ |
|
|
|
|
ExifData* exifData = exif_data_new_from_data(reinterpret_cast<const unsigned char*>(data), size); |
|
|
|
|
|
|
|
|
|
if (!exifData) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
int orientation = 0; |
|
|
|
|
const ExifByteOrder byteOrder = exif_data_get_byte_order(exifData); |
|
|
|
|
const ExifEntry* const exifEntry = exif_data_get_entry(exifData, EXIF_TAG_ORIENTATION); |
|
|
|
|
if (exifEntry) { |
|
|
|
|
orientation = exif_get_short(exifEntry->data, byteOrder); |
|
|
|
|
} |
|
|
|
|
exif_data_free(exifData); |
|
|
|
|
return orientation; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FileTransferWidget::applyTransformation(const int orientation, QImage& image) |
|
|
|
|
{ |
|
|
|
|
QTransform exifTransform; |
|
|
|
|
switch(static_cast<ExifOrientation>(orientation)) |
|
|
|
|
{ |
|
|
|
|
case ExifOrientation::TopLeft: |
|
|
|
|
break; |
|
|
|
|
case ExifOrientation::TopRight: |
|
|
|
|
image = image.mirrored(1,0); |
|
|
|
|
break; |
|
|
|
|
case ExifOrientation::BottomRight: |
|
|
|
|
exifTransform.rotate(180); |
|
|
|
|
break; |
|
|
|
|
case ExifOrientation::BottomLeft: |
|
|
|
|
image = image.mirrored(0, 1); |
|
|
|
|
break; |
|
|
|
|
case ExifOrientation::LeftTop: |
|
|
|
|
exifTransform.rotate(90); |
|
|
|
|
image = image.mirrored(0, 1); |
|
|
|
|
break; |
|
|
|
|
case ExifOrientation::RightTop: |
|
|
|
|
exifTransform.rotate(-90); |
|
|
|
|
break; |
|
|
|
|
case ExifOrientation::RightBottom: |
|
|
|
|
exifTransform.rotate(-90); |
|
|
|
|
image = image.mirrored(0, 1); |
|
|
|
|
break; |
|
|
|
|
case ExifOrientation::LeftBottom: |
|
|
|
|
exifTransform.rotate(90); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
qWarning() << "Invalid exif orientation passed to applyTransformation!"; |
|
|
|
|
} |
|
|
|
|
image = image.transformed(exifTransform); |
|
|
|
|
} |
|
|
|
|