diff --git a/pixbufmanipulator.cpp b/pixbufmanipulator.cpp
index 0f774adc098f51cd48d7a9888cf3b2a886faf8ed..65a6e4f15fa86e9aba2b8ecab1163e634640729d 100644
--- a/pixbufmanipulator.cpp
+++ b/pixbufmanipulator.cpp
@@ -26,6 +26,7 @@
 #include <QIODevice>
 #include <QByteArray>
 #include <QBuffer>
+#include <QPainter>
 
 #include "person.h"
 #include "call.h"
@@ -34,7 +35,7 @@
 #include "profile.h"
 
 #include "utils.h"
-
+#include "ringthemeutils.h"
 #undef interface
 
 /*Namespace Interfaces collide with QBuffer*/
@@ -49,10 +50,6 @@ QByteArray QImageToByteArray(QImage image)
 
 namespace Interfaces {
 
-PixbufManipulator::PixbufManipulator()
-    : fallbackAvatar_(QImage(":/images/user/btn-default-userpic.svg"))
-{}
-
 QImage
 PixbufManipulator::scaleAndFrame(const QImage photo, const QSize& size)
 {
@@ -63,7 +60,9 @@ QVariant
 PixbufManipulator::callPhoto(Call* c, const QSize& size, bool displayPresence)
 {
     if (!c || c->type() == Call::Type::CONFERENCE){
-        return QVariant::fromValue(scaleAndFrame(fallbackAvatar_, size));
+        return QVariant::fromValue(fallbackAvatar(size,
+                                                  c->peerContactMethod()->uri().userinfo().at(0).toLatin1(),
+                                                  c->peerContactMethod()->bestName().at(0).toUpper().toLatin1()));
     }
     return callPhoto(c->peerContactMethod(), size, displayPresence);
 }
@@ -74,7 +73,9 @@ PixbufManipulator::callPhoto(const ContactMethod* n, const QSize& size, bool dis
     if (n && n->contact()) {
         return contactPhoto(n->contact(), size, displayPresence);
     } else {
-        return QVariant::fromValue(scaleAndFrame(fallbackAvatar_, size));
+        return QVariant::fromValue(fallbackAvatar(size,
+                                                  n->uri().userinfo().at(0).toLatin1(),
+                                                  n->bestName().at(0).toUpper().toLatin1()));
     }
 }
 
@@ -93,7 +94,9 @@ PixbufManipulator::contactPhoto(Person* c, const QSize& size, bool displayPresen
     if (c->photo().isValid()){
         photo = c->photo().value<QImage>();
     } else {
-        photo = fallbackAvatar_;
+        photo = fallbackAvatar(size,
+                               c->phoneNumbers().at(0)->uri().userinfo().at(0).toLatin1(),
+                               c->phoneNumbers().at(0)->bestName().at(0).toUpper().toLatin1());
     }
     return QVariant::fromValue(scaleAndFrame(photo, size));
 }
@@ -105,7 +108,7 @@ QVariant PixbufManipulator::personPhoto(const QByteArray& data, const QString& t
     const char* c_str2 = ba.data();
     if (avatar.loadFromData(data.fromBase64(data), c_str2))
         return Utils::getCirclePhoto(avatar, avatar.size().width());
-    return fallbackAvatar_;
+    return fallbackAvatar(imgSize_, '?', '?');
 }
 
 QVariant
@@ -182,7 +185,9 @@ QVariant PixbufManipulator::decorationRole(const Call* c)
         photo =  c->peerContactMethod()->contact()->photo().value<QImage>();
     }
     else
-        photo = fallbackAvatar_;
+        photo = fallbackAvatar(imgSize_,
+                               c->peerContactMethod()->uri().userinfo().at(0).toLatin1(),
+                               c->peerContactMethod()->bestName().at(0).toUpper().toLatin1());
     return QVariant::fromValue(scaleAndFrame(photo, imgSize_));
 }
 
@@ -192,7 +197,9 @@ QVariant PixbufManipulator::decorationRole(const ContactMethod* cm)
     if (cm && cm->contact() && cm->contact()->photo().isValid())
         photo = cm->contact()->photo().value<QImage>();
     else
-        photo = fallbackAvatar_;
+        photo = fallbackAvatar(imgSize_,
+                               cm->uri().userinfo().at(0).toLatin1(),
+                               cm->bestName().at(0).toUpper().toLatin1());
     return QVariant::fromValue(scaleAndFrame(photo, imgSize_));
 }
 
@@ -202,7 +209,9 @@ QVariant PixbufManipulator::decorationRole(const Person* p)
     if (p && p->photo().isValid())
         photo = p->photo().value<QImage>();
     else
-        photo = fallbackAvatar_;
+        photo = fallbackAvatar(imgSize_,
+                               p->phoneNumbers().at(0)->uri().userinfo().at(0).toLatin1(),
+                               p->phoneNumbers().at(0)->bestName().at(0).toUpper().toLatin1());
     return QVariant::fromValue(scaleAndFrame(photo, imgSize_));
 }
 
@@ -214,4 +223,31 @@ QVariant PixbufManipulator::decorationRole(const Account* acc)
                                      imgSize_.width());
 }
 
+QImage PixbufManipulator::fallbackAvatar(const QSize size, const char color, const char letter)
+{
+    // We start with a transparent avatar
+    QImage avatar(size, QImage::Format_ARGB32);
+    avatar.fill(Qt::transparent);
+
+    // We pick a color based on the passed character
+    QColor avColor = RingTheme::avatarColors_[color % 16];
+
+    // We draw a circle with this color
+    QPainter painter(&avatar);
+    painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
+    painter.setPen(Qt::transparent);
+    painter.setBrush(avColor);
+    painter.drawEllipse(avatar.rect());
+
+    // Then we paint a letter in the circle
+    QFont segoeFont("Segoe UI", avatar.height()/2); // We use Segoe UI as recommended by Windows guidelines
+    painter.setFont(segoeFont);
+    painter.setPen(Qt::white);
+    QRect textRect = avatar.rect();
+    textRect.moveTop(textRect.top()-(avatar.height()/20)); // Empirical value that seems to correct centering nicely
+    painter.drawText(textRect, QString(letter), QTextOption(Qt::AlignCenter));
+
+    return avatar;
+}
+
 } // namespace Interfaces
diff --git a/pixbufmanipulator.h b/pixbufmanipulator.h
index 7ebc92b8c9528b40e5f0b3af36040bec5f785696..2abbc9a4b3d7c3fc303e3114033f9aec9fc4842f 100644
--- a/pixbufmanipulator.h
+++ b/pixbufmanipulator.h
@@ -33,8 +33,6 @@ namespace Interfaces {
 
 class PixbufManipulator : public PixmapManipulatorI {
 public:
-    PixbufManipulator();
-
     QVariant callPhoto(Call* c, const QSize& size, bool displayPresence = true) override;
     QVariant callPhoto(const ContactMethod* n, const QSize& size, bool displayPresence = true) override;
     QVariant contactPhoto(Person* c, const QSize& size, bool displayPresence = true) override;
@@ -56,9 +54,9 @@ public:
     QVariant   decorationRole(const Account* acc) override;
 
 private:
-    QImage fallbackAvatar_;
     QImage scaleAndFrame(const QImage photo, const QSize& size);
     const QSize imgSize_ {48, 48};
+    static QImage fallbackAvatar(const QSize size, const char color, const char letter);
 };
 
 } // namespace Interfaces
diff --git a/ringthemeutils.h b/ringthemeutils.h
index 659fe9c8f04b550f7aa5cf24863cd43967fd6191..c5f6896432f89d82a057d3ef88bd6fe8a2707161 100644
--- a/ringthemeutils.h
+++ b/ringthemeutils.h
@@ -32,4 +32,23 @@ static const QColor lightRed_ {252, 91, 90};
 static const QColor darkRed_ {219, 55, 54};
 static const QColor green_ {127, 255, 0};
 
+static const QColor avatarColors_[] {
+    {"#fff44336"}, //Red
+    {"#ffe91e63"}, //Pink
+    {"#ff9c27b0"}, //Purple
+    {"#ff673ab7"}, //Deep Purple
+    {"#ff3f51b5"}, //Indigo
+    {"#ff2196f3"}, //Blue
+    {"#ff00bcd4"}, //Cyan
+    {"#ff009688"}, //Teal
+    {"#ff4caf50"}, //Green
+    {"#ff8bc34a"}, //Light Green
+    {"#ff9e9e9e"}, //Grey
+    {"#ffcddc39"}, //Lime
+    {"#ffffc107"}, //Amber
+    {"#ffff5722"}, //Deep Orange
+    {"#ff795548"}, //Brown
+    {"#ff607d8b"}  //Blue Grey
+};
+
 }