diff --git a/src/accountadapter.cpp b/src/accountadapter.cpp
index ebf0de238b17f4fa3e33be40edf117ccf9f8ce06..7ac854291a7d14e83489523e5a32c1dcfd2f519b 100644
--- a/src/accountadapter.cpp
+++ b/src/accountadapter.cpp
@@ -25,6 +25,8 @@
 
 #include "qtutils.h"
 
+#include <QtConcurrent/QtConcurrent>
+
 #undef REGISTERED
 #include "../daemon/src/dring/account_const.h"
 
@@ -89,13 +91,12 @@ AccountAdapter::connectFailure()
 void
 AccountAdapter::createJamiAccount(QString registeredName,
                                   const QVariantMap& settings,
-                                  QString photoBoothImgBase64,
                                   bool isCreating)
 {
     Utils::oneShotConnect(
         &LRCInstance::accountModel(),
         &lrc::api::NewAccountModel::accountAdded,
-        [this, registeredName, settings, isCreating, photoBoothImgBase64](const QString& accountId) {
+        [this, registeredName, settings, isCreating](const QString& accountId) {
             auto showBackup = isCreating
                               && !AppSettingsManager::getValue(Settings::Key::NeverShowMeAgain)
                                       .toBool();
@@ -124,16 +125,6 @@ AccountAdapter::createJamiAccount(QString registeredName,
                                   showBackup,
                                   LRCInstance::accountModel().getAccountList().indexOf(accountId));
             }
-
-            // set up avatar pixmap from photobooth
-            QImage avatarImg;
-            const bool ret = avatarImg.loadFromData(
-                QByteArray::fromBase64(photoBoothImgBase64.toLatin1()));
-            if (!ret) {
-                qDebug() << "No image provided for JAMI account creation";
-            } else {
-                LRCInstance::setAvatarForAccount(QPixmap::fromImage(avatarImg), accountId);
-            }
         });
 
     connectFailure();
@@ -156,11 +147,11 @@ AccountAdapter::createJamiAccount(QString registeredName,
 }
 
 void
-AccountAdapter::createSIPAccount(const QVariantMap& settings, QString photoBoothImgBase64)
+AccountAdapter::createSIPAccount(const QVariantMap& settings)
 {
     Utils::oneShotConnect(&LRCInstance::accountModel(),
                           &lrc::api::NewAccountModel::accountAdded,
-                          [this, settings, photoBoothImgBase64](const QString& accountId) {
+                          [this, settings](const QString& accountId) {
                               auto confProps = LRCInstance::accountModel().getAccountConfig(
                                   accountId);
                               // set SIP details
@@ -170,17 +161,6 @@ AccountAdapter::createSIPAccount(const QVariantMap& settings, QString photoBooth
                               confProps.routeset = settings["proxy"].toString();
                               LRCInstance::accountModel().setAccountConfig(accountId, confProps);
 
-                              // set up photobooth avatar to SIP avatar
-                              QImage avatarImg;
-                              const bool ret = avatarImg.loadFromData(
-                                  QByteArray::fromBase64(photoBoothImgBase64.toLatin1()));
-                              if (!ret) {
-                                  qDebug() << "SIP account creation BASE64 image loading failed";
-                              } else {
-                                  LRCInstance::setAvatarForAccount(QPixmap::fromImage(avatarImg),
-                                                                   accountId);
-                              }
-
                               emit LRCInstance::instance().accountListChanged();
                               emit accountAdded(accountId,
                                                 false,
@@ -294,6 +274,22 @@ AccountAdapter::getCurrentAccountType()
     return LRCInstance::getCurrentAccountInfo().profileInfo.type;
 }
 
+void
+AccountAdapter::setCurrAccAvatar(bool fromFile, const QString& source)
+{
+    QtConcurrent::run([fromFile, source]() {
+        QPixmap image;
+        bool success;
+        if (fromFile)
+            success = image.load(source);
+        else
+            success = image.loadFromData(Utils::base64StringToByteArray(source));
+
+        if (success)
+            LRCInstance::setCurrAccAvatar(image);
+    });
+}
+
 void
 AccountAdapter::onCurrentAccountChanged()
 {
diff --git a/src/accountadapter.h b/src/accountadapter.h
index 4405e345e3e3e4f142b7bd7552b606cd1ee0ca19..cdcc7561709e3bfdf7b1b61ccb1799c24550636b 100644
--- a/src/accountadapter.h
+++ b/src/accountadapter.h
@@ -66,9 +66,8 @@ public:
      */
     Q_INVOKABLE void createJamiAccount(QString registeredName,
                                        const QVariantMap& settings,
-                                       QString photoBoothImgBase64,
                                        bool isCreating);
-    Q_INVOKABLE void createSIPAccount(const QVariantMap& settings, QString photoBoothImgBase64);
+    Q_INVOKABLE void createSIPAccount(const QVariantMap& settings);
     Q_INVOKABLE void createJAMSAccount(const QVariantMap& settings);
     /*
      * Delete current account
@@ -102,6 +101,8 @@ public:
     Q_INVOKABLE void setSelectedConvId(const QString& convId = {});
     Q_INVOKABLE lrc::api::profile::Type getCurrentAccountType();
 
+    Q_INVOKABLE void setCurrAccAvatar(bool fromFile, const QString& source);
+
 signals:
     /*
      * Trigger other components to reconnect account related signals.
diff --git a/src/avadapter.cpp b/src/avadapter.cpp
index 91cd9e2a4835b78455e2ae46b032dae9be0ebfdf..b1cfb98838668f1ee966910d641b478fc66dffa2 100644
--- a/src/avadapter.cpp
+++ b/src/avadapter.cpp
@@ -99,7 +99,7 @@ AvAdapter::captureScreen(int screenNumber)
     QBuffer buffer;
     buffer.open(QIODevice::WriteOnly);
     pixmap.save(&buffer, "PNG");
-    return QString::fromLatin1(buffer.data().toBase64().data());
+    return Utils::byteArrayToBase64String(buffer.data());
 }
 
 void
diff --git a/src/avatarimageprovider.h b/src/avatarimageprovider.h
index 336a22bb35ccccce5cb7eaa0e18c907c6cefb59e..29d074f0c22b27aee246ba5133ed5b1eda006565 100644
--- a/src/avatarimageprovider.h
+++ b/src/avatarimageprovider.h
@@ -38,6 +38,7 @@ public:
      * 2. file_ + file path
      * 3. contact_+ contact uri
      * 4. conversation_+ conversation uid
+     * 5. base64_ + base64 string
      */
     QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize) override
     {
@@ -65,11 +66,13 @@ public:
             return Utils::fallbackAvatar(QString(), idContent, requestedSize);
         } else if (idType == "default") {
             return Utils::fallbackAvatar(QString(), QString(), requestedSize);
+        } else if (idType == "base64") {
+            return Utils::cropImage(QImage::fromData(Utils::base64StringToByteArray(idContent)))
+                .scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
         } else {
-            auto image = Utils::cropImage(QImage(idContent));
-            return image.scaled(requestedSize,
-                                Qt::KeepAspectRatioByExpanding,
-                                Qt::SmoothTransformation);
+            QImage image = QImage(idContent);
+            return Utils::getCirclePhoto(image, image.size().width())
+                .scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
         }
     }
 };
diff --git a/src/commoncomponents/AvatarImage.qml b/src/commoncomponents/AvatarImage.qml
index 61b68a74a01e79163235d6ef9538be4a3db88324..bfd74876939d934de177d978020578bcb5a7cf4b 100644
--- a/src/commoncomponents/AvatarImage.qml
+++ b/src/commoncomponents/AvatarImage.qml
@@ -24,19 +24,19 @@ import net.jami.Constants 1.0
 Item {
     id: root
 
-    // FromUrl here is for grabToImage image url
     enum Mode {
         FromAccount = 0,
         FromFile,
         FromContactUri,
         FromConvUid,
-        FromUrl,
+        FromBase64,
         FromTemporaryName,
         Default
     }
 
     property alias fillMode: rootImage.fillMode
     property alias sourceSize: rootImage.sourceSize
+    property bool saveToConfig: false
     property int mode: AvatarImage.Mode.FromAccount
     property string imageProviderIdPrefix: {
         switch(mode) {
@@ -50,6 +50,8 @@ Item {
             return "conversation_"
         case AvatarImage.Mode.FromTemporaryName:
             return "fallback_"
+        case AvatarImage.Mode.FromBase64:
+            return "base64_"
         case AvatarImage.Mode.Default:
             return "default_"
         default:
@@ -69,6 +71,19 @@ Item {
 
     signal imageIsReady
 
+    function saveAvatarToConfig() {
+        switch(mode) {
+        case AvatarImage.Mode.FromFile:
+            AccountAdapter.setCurrAccAvatar(true, imageId)
+            break
+        case AvatarImage.Mode.FromBase64:
+            AccountAdapter.setCurrAccAvatar(false, imageId)
+            break
+        default:
+            return
+        }
+    }
+
     function updateImage(updatedId, oneTimeForceUpdateUrl) {
         imageId = updatedId
         if (oneTimeForceUpdateUrl === undefined)
@@ -76,10 +91,10 @@ Item {
         else
             forceUpdateUrl = oneTimeForceUpdateUrl
 
-        if (mode === AvatarImage.Mode.FromUrl)
-            rootImage.source = imageId
-        else
-            rootImage.source = imageProviderUrl + imageId
+        rootImage.source = imageProviderUrl + imageId
+
+        if (saveToConfig)
+            saveAvatarToConfig()
     }
 
     Image {
@@ -192,5 +207,4 @@ Item {
         radius: 30
         color: JamiTheme.notificationRed
     }
-
 }
diff --git a/src/commoncomponents/PhotoboothView.qml b/src/commoncomponents/PhotoboothView.qml
index f88ff3ea425b0e33d5db0c1e7ab4fe5ca1b1bb89..78b3d9c1fcf8eca80e7a950b7829cd589e0f71f5 100644
--- a/src/commoncomponents/PhotoboothView.qml
+++ b/src/commoncomponents/PhotoboothView.qml
@@ -12,9 +12,8 @@ ColumnLayout {
     property int photoState: PhotoboothView.PhotoState.Default
     property bool avatarSet: false
     // saveToConfig is to specify whether the image should be saved to account config
-    property bool saveToConfig: false
+    property alias saveToConfig: avatarImg.saveToConfig
     property string fileName: ""
-    property var boothImg: ""
 
     property int boothWidth: 224
 
@@ -50,7 +49,7 @@ ColumnLayout {
 
     function setAvatarImage(mode = AvatarImage.Mode.FromAccount,
                             imageId = AccountAdapter.currentAccountId){
-        if (mode !== AvatarImage.Mode.FromUrl)
+        if (mode !== AvatarImage.Mode.FromBase64)
             avatarImg.enableAnimation = true
         else
             avatarImg.enableAnimation = false
@@ -58,7 +57,6 @@ ColumnLayout {
         avatarImg.mode = mode
 
         if (mode === AvatarImage.Mode.Default) {
-            boothImg = ""
             avatarImg.updateImage(imageId)
             return
         }
@@ -67,6 +65,10 @@ ColumnLayout {
             avatarImg.updateImage(imageId)
     }
 
+    function manualSaveToConfig() {
+        avatarImg.saveAvatarToConfig()
+    }
+
     onVisibleChanged: {
         if(!visible){
             stopBooth()
@@ -141,21 +143,12 @@ ColumnLayout {
                 }
 
                 onImageIsReady: {
-                    if (mode === AvatarImage.Mode.FromUrl)
+                    if (mode === AvatarImage.Mode.FromBase64)
                         photoState = PhotoboothView.PhotoState.Taken
 
                     if (photoState === PhotoboothView.PhotoState.Taken) {
                         avatarImg.state = ""
                         avatarImg.state = "flashIn"
-                    } else {
-                        // Once image is loaded (updated), save to boothImg (choose from file)
-                        avatarImg.grabToImage(function(result) {
-                            if (mode !== AvatarImage.Mode.Default)
-                                boothImg = result.image
-
-                            if (saveToConfig)
-                                SettingsAdapter.setCurrAccAvatar(result.image)
-                        })
                     }
                 }
 
@@ -255,17 +248,11 @@ ColumnLayout {
                     startBooth()
                     return
                 } else {
-                    previewWidget.grabToImage(function(result) {
-                        boothImg = result.image
-
-                        if (saveToConfig)
-                            SettingsAdapter.setCurrAccAvatar(result.image)
-
-                        setAvatarImage(AvatarImage.Mode.FromUrl, result.url)
+                    setAvatarImage(AvatarImage.Mode.FromBase64,
+                                   previewWidget.takePhoto(boothWidth))
 
-                        avatarSet = true
-                        stopBooth()
-                    })
+                    avatarSet = true
+                    stopBooth()
                 }
             }
         }
diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp
index da4186f99748ff87264862c877e02440b6572d9d..819285bd3ce0560ad9d2d864c84d2e1e315917ab 100644
--- a/src/messagesadapter.cpp
+++ b/src/messagesadapter.cpp
@@ -396,7 +396,7 @@ MessagesAdapter::pasteKeyDetected()
         QBuffer bu(&ba);
         bu.open(QIODevice::WriteOnly);
         pixmap.save(&bu, "PNG");
-        auto str = QString::fromLatin1(ba.toBase64().data());
+        auto str = Utils::byteArrayToBase64String(ba);
 
         setMessagesImageContent(str, true);
     } else if (mimeData->hasUrls()) {
diff --git a/src/previewrenderer.cpp b/src/previewrenderer.cpp
index 92cd0f0cb46576f66cae971b795a6419fa6c64c3..e966a20eeea4578f87874a84741218360f27222d 100644
--- a/src/previewrenderer.cpp
+++ b/src/previewrenderer.cpp
@@ -112,6 +112,16 @@ PhotoboothPreviewRender::PhotoboothPreviewRender(QQuickItem* parent)
 
 PhotoboothPreviewRender::~PhotoboothPreviewRender() {}
 
+QString
+PhotoboothPreviewRender::takePhoto(int size)
+{
+    if (auto previewImage = LRCInstance::renderer()->getPreviewFrame()) {
+        return Utils::byteArrayToBase64String(Utils::QImageToByteArray(
+            previewImage->copy()
+                .scaled(size, size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation)));
+    }
+}
+
 void
 PhotoboothPreviewRender::paint(QPainter* painter)
 {
diff --git a/src/previewrenderer.h b/src/previewrenderer.h
index 55249b1248a8498bb6326f9f6ca20a7b60d47030..715121c3b1e308c7b95981241c9327c70993f2ea 100644
--- a/src/previewrenderer.h
+++ b/src/previewrenderer.h
@@ -63,6 +63,8 @@ public:
     explicit PhotoboothPreviewRender(QQuickItem* parent = 0);
     virtual ~PhotoboothPreviewRender();
 
+    Q_INVOKABLE QString takePhoto(int size);
+
 signals:
     void hideBooth();
 
diff --git a/src/settingsadapter.cpp b/src/settingsadapter.cpp
index e81c45f3684d8a91c186330897f5432a6e9f439d..a4022bac481de333d3f778a74378e02fd983ed67 100644
--- a/src/settingsadapter.cpp
+++ b/src/settingsadapter.cpp
@@ -263,26 +263,6 @@ SettingsAdapter::getAccountBestName()
     return LRCInstance::accountModel().bestNameForAccount(LRCInstance::getCurrAccId());
 }
 
-bool
-SettingsAdapter::getIsDefaultAvatar()
-{
-    auto& accountInfo = LRCInstance::getCurrentAccountInfo();
-
-    return accountInfo.profileInfo.avatar.isEmpty();
-}
-
-void
-SettingsAdapter::setCurrAccAvatar(QVariant avatarImg)
-{
-    LRCInstance::setCurrAccAvatar(QPixmap::fromImage(avatarImg.value<QImage>()));
-}
-
-void
-SettingsAdapter::clearCurrentAvatar()
-{
-    LRCInstance::setCurrAccAvatar(QPixmap());
-}
-
 lrc::api::account::ConfProperties_t
 SettingsAdapter::getAccountConfig()
 {
diff --git a/src/settingsadapter.h b/src/settingsadapter.h
index 405b7385407293b0f203bb454c8a3369fcd69347..53e1f1569b5419905edbd3ce1cc05ae6d7042192 100644
--- a/src/settingsadapter.h
+++ b/src/settingsadapter.h
@@ -93,11 +93,6 @@ public:
     Q_INVOKABLE int getCurrentAccount_Profile_Info_Type();
     Q_INVOKABLE QString getAccountBestName();
 
-    // getters and setters of avatar image
-    Q_INVOKABLE bool getIsDefaultAvatar();
-    Q_INVOKABLE void setCurrAccAvatar(QVariant avatarImg);
-    Q_INVOKABLE void clearCurrentAvatar();
-
     /*
      * getters and setters of ConfProperties_t
      */
diff --git a/src/utils.cpp b/src/utils.cpp
index b38484f7ea951b661749b4afd5ca6377191a1d72..327cdc679302d4e3206bf42acccb84ef8e0f02e2 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -265,7 +265,7 @@ Utils::contactPhoto(const QString& contactUri, const QSize& size)
                    && contactInfo.profileInfo.uri.isEmpty()) {
             photo = Utils::fallbackAvatar(QString(), QString());
         } else if (!contactPhoto.isEmpty()) {
-            QByteArray byteArray = contactPhoto.toLocal8Bit();
+            QByteArray byteArray = Utils::base64StringToByteArray(contactPhoto);
             photo = contactPhotoFromBase64(byteArray, nullptr);
             if (photo.isNull()) {
                 auto avatarName = contactInfo.profileInfo.uri == bestName ? QString() : bestName;
@@ -284,7 +284,7 @@ QImage
 Utils::contactPhotoFromBase64(const QByteArray& data, const QString& type)
 {
     QImage avatar;
-    const bool ret = avatar.loadFromData(QByteArray::fromBase64(data), type.toLatin1());
+    const bool ret = avatar.loadFromData(data, type.toLatin1());
     if (!ret) {
         qDebug() << "Utils: vCard image loading failed";
         return QImage();
@@ -587,6 +587,18 @@ Utils::QImageToByteArray(QImage image)
     return ba;
 }
 
+QString
+Utils::byteArrayToBase64String(QByteArray byteArray)
+{
+    return QString::fromLatin1(byteArray.toBase64().data());
+}
+
+QByteArray
+Utils::base64StringToByteArray(QString base64)
+{
+    return QByteArray::fromBase64(base64.toLatin1());
+}
+
 QImage
 Utils::cropImage(const QImage& img)
 {
@@ -718,7 +730,7 @@ Utils::accountPhoto(const lrc::api::account::Info& accountInfo, const QSize& siz
 {
     QImage photo;
     if (!accountInfo.profileInfo.avatar.isEmpty()) {
-        QByteArray ba = accountInfo.profileInfo.avatar.toLocal8Bit();
+        QByteArray ba = Utils::base64StringToByteArray(accountInfo.profileInfo.avatar);
         photo = contactPhotoFromBase64(ba, nullptr);
     } else {
         auto bestId = LRCInstance::accountModel().bestIdForAccount(accountInfo.id);
diff --git a/src/utils.h b/src/utils.h
index 2a7781fb3e16a9610ddb46ddf74f8cc52bdfaa69..f21958ea3857c25a5a1d27b6795d52459d9fc99f 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -101,6 +101,8 @@ QImage fallbackAvatar(const std::string& alias,
                       const std::string& uri,
                       const QSize& size = defaultAvatarSize);
 QByteArray QImageToByteArray(QImage image);
+QString byteArrayToBase64String(QByteArray byteArray);
+QByteArray base64StringToByteArray(QString base64);
 QByteArray QByteArrayFromFile(const QString& filename);
 QPixmap generateTintedPixmap(const QString& filename, QColor color);
 QPixmap generateTintedPixmap(const QPixmap& pix, QColor color);
diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml
index 47c9947372aec5aa0fbfa1a1c6102527beb571b4..b3d80c587dd026a5fb04a2d6b9bdf9d50ef150f2 100644
--- a/src/wizardview/WizardView.qml
+++ b/src/wizardview/WizardView.qml
@@ -238,7 +238,6 @@ Rectangle {
                     AccountAdapter.createJamiAccount(
                         createAccountPage.text_usernameEditAlias,
                         inputParaObject,
-                        createAccountPage.boothImgBase64,
                         true)
                     showBackUp = !isRdv
                     showBottom = true
@@ -391,8 +390,7 @@ Rectangle {
                 }
 
                 onSaveProfile: {
-                    if (profilePage.profileImg)
-                        SettingsAdapter.setCurrAccAvatar(profilePage.profileImg)
+                    avatarBooth.manualSaveToConfig()
                     AccountAdapter.setCurrAccDisplayName(profilePage.displayName)
                     leave()
                 }
diff --git a/src/wizardview/components/ProfilePage.qml b/src/wizardview/components/ProfilePage.qml
index 91e0acbe2cc8ebd1133473d3f11ad21d1bded535..cd7e72f2d089bd6e873acdd8c077627e61c0ec4b 100644
--- a/src/wizardview/components/ProfilePage.qml
+++ b/src/wizardview/components/ProfilePage.qml
@@ -27,11 +27,11 @@ Rectangle {
     id: root
 
     property string createdAccountId: ""
-    property alias profileImg: setAvatarWidget.boothImg
     property int preferredHeight: profilePageColumnLayout.implicitHeight
     property var showBottom: false
     property alias displayName: aliasEdit.text
     property bool isRdv: false
+    property alias avatarBooth: setAvatarWidget
 
     signal leavePage
     signal saveProfile