From 3b07b10b1905e0dfad68864aa79be9e7da9a6b2c Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Sun, 25 Oct 2026 00:11:09 +0200 Subject: [PATCH] [Avatar] Respect EXIF orientation and decode at target size (#7634) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read the avatar with setAutoTransform(true) so camera orientation is applied, and ask QImageReader for a scaled decode at MAX_AVATAR_DIMENSION instead of decoding a full-resolution photo and scaling it afterwards. Verification: cockatrice built. Co-authored-by: Lukas BrĂ¼bach --- .../interface/widgets/dialogs/dlg_edit_avatar.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp index 520ece007..7f0141bd5 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp @@ -71,7 +71,21 @@ void DlgEditAvatar::actBrowse() QImageReader imgReader; imgReader.setDecideFormatFromContent(true); + // Honour the EXIF orientation phone cameras write; otherwise portrait + // photos are shown and stored sideways. + imgReader.setAutoTransform(true); imgReader.setFileName(fileName); + + // Decode straight to the maximum avatar size. Scaling afterwards decodes + // the full-resolution image first, which can be tens of megabytes for a + // modern camera photo. + const QSize sourceSize = imgReader.size(); + if (sourceSize.isValid() && + (sourceSize.width() > MAX_AVATAR_DIMENSION || sourceSize.height() > MAX_AVATAR_DIMENSION)) { + const QSize targetSize = sourceSize.scaled(MAX_AVATAR_DIMENSION, MAX_AVATAR_DIMENSION, Qt::KeepAspectRatio); + imgReader.setScaledSize(targetSize); + } + if (!imgReader.read(&image)) { qCWarning(DlgEditAvatarLog) << "Avatar image loading failed for file:" << fileName; imageLabel->setText(tr("Invalid image chosen."));