Commit 767824b121431c554e78b1d268c6b70b99cb0bc3

Authored by OpenWapp Developer
1 parent e279d14735

Force profile images to be square and autoscale when they are not.

Showing 7 changed files with 51 additions and 16 deletions

app/scripts/localisations/translation.js View file @ 767824b
... ... @@ -184,7 +184,7 @@
184 184 accountExpiration: 'Fecha de expiración',
185 185 upgradeNow: 'Actualizar ahora',
186 186 notSquarePicture: 'La imagen seleccionada no es cuadrada. Esto hará que' +
187   - ' aparezcan bandas blancas en los laterales. Si quieres arreglarlo, ' +
  187 + ' aparezcan bandas de relleno alrededor. Si quieres arreglarlo, ' +
188 188 'abre la aplicación de Galería y edita y recorta la imagen para que ' +
189 189 'tenga un aspecto 1:1'
190 190 },
... ... @@ -374,7 +374,7 @@
374 374 accountExpiration: 'Expiration date',
375 375 upgradeNow: 'Upgrade now',
376 376 notSquarePicture: 'The selected image is not square. This will make to ' +
377   - 'appear white bands in the laterals. If you want to fix it, go to the ' +
  377 + 'appear padding bands around. If you want to fix it, go to the ' +
378 378 'Gallery, and edit and crop the photo, using a 1:1 aspect ratio.'
379 379 },
380 380 pt : {
... ... @@ -560,7 +560,7 @@
560 560 accountExpiration: 'Data de validade',
561 561 upgradeNow: 'Actualizar agora',
562 562 notSquarePicture: 'A imagem selecionada não é quadrado. Isso fará com ' +
563   - 'que apareçam faixas brancas nas laterais. Se você quiser corrigi-lo, ' +
  563 + 'que apareçam faixas ao redor. Se você quiser corrigi-lo, ' +
564 564 'vá até a Galeria e editar e cortar a foto, usando uma relação de ' +
565 565 'aspecto de 1:1.'
566 566 },
... ... @@ -748,7 +748,7 @@
748 748 accountExpiration: 'Data de validade',
749 749 upgradeNow: 'Actualizar agora',
750 750 notSquarePicture: 'A imagem selecionada não é quadrado. Isso fará com ' +
751   - 'que apareçam faixas brancas nas laterais. Se você quiser corrigi-lo, ' +
  751 + 'que apareçam faixas ao redor. Se você quiser corrigi-lo, ' +
752 752 'vá até a Galeria e editar e cortar a foto, usando uma relação de ' +
753 753 'aspecto de 1:1.'
754 754 }
app/scripts/templates/group-profile.hbs View file @ 767824b
... ... @@ -22,6 +22,7 @@
22 22 <img id="profile-picture" type="text" src="/images/unknown_avatar.png"
23 23 alt="{{translate 'groupPictureDescription'}}"/>
24 24 </p>
  25 + <p class="not-square hidden">{{translate 'notSquarePicture'}}</p>
25 26 <p>{{translate 'groupPictureDescription'}}</p>
26 27 <p>
27 28 <input type="text" max="{{maxSubjectLength}}"
app/scripts/templates/profile.hbs View file @ 767824b
... ... @@ -24,6 +24,7 @@
24 24 <img id="profile-picture" type="text" src="/images/unknown_avatar.png"
25 25 alt="Avatar"/>
26 26 </p>
  27 + <p class="not-square hidden">{{translate 'notSquarePicture'}}</p>
27 28 <p>{{translate 'pictureDescription'}}</p>
28 29 <p>
29 30 <input type="text"
app/scripts/utils/thumbnail.js View file @ 767824b
... ... @@ -11,6 +11,7 @@
11 11 options = options || {};
12 12 var maxSize = this.maxSize || DEFAULT_MAX_SIZE;
13 13 var quality = options.quality || 0.8;
  14 + var forceSquare = options.forceSquare || false;
14 15  
15 16 var fileReader = new FileReader();
16 17 fileReader.readAsDataURL(imageBlob);
17 18  
18 19  
19 20  
20 21  
... ... @@ -23,18 +24,32 @@
23 24 height = img.height;
24 25  
25 26 var scale = Math.min(maxSize / Math.max(height, width), 1);
  27 + var ratio = width / height;
26 28  
27 29 var c = document.createElement('canvas');
28   - c.width = width * scale;
29   - c.height = height * scale;
  30 + var newWidth = width * scale;
  31 + var newHeight = height * scale;
  32 + if (forceSquare) {
  33 + c.width = Math.max(newWidth, newHeight);
  34 + c.height = c.width;
  35 + }
  36 + else {
  37 + c.width = newWidth;
  38 + c.height = newHeight;
  39 + }
30 40  
31 41 var ctx = c.getContext('2d');
32   - ctx.drawImage(img, 0, 0, width * scale, height * scale);
  42 + var offsetX = (c.width - newWidth) / 2;
  43 + var offsetY = (c.height - newHeight) / 2;
  44 + ctx.drawImage(img, offsetX, offsetY, newWidth, newHeight);
33 45  
34 46 if (options.asBlob) {
35   - c.toBlob(callback.bind(null, null), 'image/jpeg', quality);
  47 + c.toBlob(function (blob) {
  48 + callback(null, blob, ratio);
  49 + }, 'image/jpeg', quality);
36 50 } else {
37   - callback(null, c.toDataURL('image/jpeg').split('base64,')[1]);
  51 + callback(
  52 + null, c.toDataURL('image/jpeg').split('base64,')[1], ratio);
38 53 }
39 54 };
40 55  
app/scripts/views/group-profile.js View file @ 767824b
... ... @@ -231,8 +231,9 @@
231 231 var picture = requestPicture.result.blob;
232 232 _this.isGroupPictureDirty = true;
233 233 Thumbnail.setMaxSize(_this.PICTURE_MAX_SIZE);
234   - Thumbnail.generate(picture, function (err, picture) {
  234 + Thumbnail.generate(picture, function (err, picture, ratio) {
235 235 if (err) { return; }
  236 + if (ratio !== 1) { _this._showNotSquareWarning(); }
236 237 _this.picture = picture;
237 238 _this._replacePhoto(picture);
238 239  
239 240  
... ... @@ -241,13 +242,17 @@
241 242 Thumbnail.generate(picture, function (err, thumb) {
242 243 if (err) { return; }
243 244 _this.thumb = thumb;
244   - }, { asBlob: true, quality: quality / 2 });
245   - }, { asBlob: true, quality: quality });
  245 + }, { asBlob: true, quality: quality / 2, forceSquare: true });
  246 + }, { asBlob: true, quality: quality, forceSquare: true });
246 247 };
247 248  
248 249 requestPicture.onerror = function () {
249 250 console.error('Impossible to get profile\'s picture.');
250 251 };
  252 + },
  253 +
  254 + _showNotSquareWarning: function () {
  255 + this.$el.find('.not-square').get(0).classList.remove('hidden');
251 256 },
252 257  
253 258 showParticipants: function () {
app/scripts/views/profile.js View file @ 767824b
... ... @@ -90,6 +90,10 @@
90 90 });
91 91 },
92 92  
  93 + _showNotSquareWarning: function () {
  94 + this.$el.find('.not-square').get(0).classList.remove('hidden');
  95 + },
  96 +
93 97 updateProfileData: function (evt) {
94 98 evt.preventDefault();
95 99  
96 100  
... ... @@ -113,8 +117,9 @@
113 117 var _this = this;
114 118 requestPicture.onsuccess = function () {
115 119 var picture = requestPicture.result.blob;
116   - _this.generatePicture(picture, function (err, resizedPic) {
  120 + _this.generatePicture(picture, function (err, resizedPic, ratio) {
117 121 if (err) { return; }
  122 + if (ratio !== 1) { _this._showNotSquareWarning(); }
118 123 _this.picture = resizedPic;
119 124 _this._replacePhoto(resizedPic);
120 125 });
121 126  
... ... @@ -133,14 +138,19 @@
133 138 generatePicture: function (picture, callback) {
134 139 var quality = global.client.getProperty('image_quality');
135 140 Thumbnail.setMaxSize(this.PICTURE_MAX_SIZE);
136   - Thumbnail.generate(picture, callback, { asBlob: true, quality: quality });
  141 + Thumbnail.generate(
  142 + picture, callback,
  143 + { asBlob: true, quality: quality, forceSquare: true }
  144 + );
137 145 },
138 146  
139 147 generateThumbnail: function (picture, callback) {
140 148 var quality = global.client.getProperty('image_quality');
141 149 Thumbnail.setMaxSize(this.THUMB_MAX_SIZE);
142   - Thumbnail
143   - .generate(picture, callback, { asBlob: true, quality: quality / 2 });
  150 + Thumbnail.generate(
  151 + picture, callback,
  152 + { asBlob: true, quality: quality / 2, forceSquare: true }
  153 + );
144 154 },
145 155  
146 156 showSelect: function () {
app/styles/_common.sass View file @ 767824b
... ... @@ -158,4 +158,7 @@
158 158 overflow-y: auto
159 159 height: -moz-calc(100% - #{$header-height})
160 160 height: -webkit-calc(100% - #{$header-height})
  161 +
  162 +.not-square
  163 + color: #FF3939