From 4a311c399e3f3302808901e59d4822e5e2410ac4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 5 Mar 2012 16:25:49 +0100 Subject: [PATCH] Generate thumbnails of high-res pictures through a canvas to avoid rendering slow downs. --- 4chan_x.user.js | 42 ++++++++++++++++++++++++++++++++++++++---- changelog | 1 + script.coffee | 46 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index f22c20724..163816960 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1569,18 +1569,52 @@ } _Class.prototype.setFile = function(file) { - var url; + var fileUrl, img, url, + _this = this; this.file = file; this.el.title = file.name; + if (qr.spoiler) $('label', this.el).hidden = false; if (file.type === 'application/pdf') { this.el.style.backgroundImage = null; return; } - if (qr.spoiler) $('label', this.el).hidden = false; url = window.URL || window.webkitURL; url.revokeObjectURL(this.url); - this.url = url.createObjectURL(file); - return this.el.style.backgroundImage = "url(" + this.url + ")"; + fileUrl = url.createObjectURL(file); + img = $.el('img'); + $.on(img, 'load', function() { + var bb, c, data, i, l, s, ui8a; + s = 90 * 3; + if (img.height < s || img.width < s) { + _this.url = fileUrl; + _this.el.style.backgroundImage = "url(" + _this.url + ")"; + return; + } + if (img.height <= img.width) { + img.width = s / img.height * img.width; + img.height = s; + } else { + img.height = s / img.width * img.height; + img.width = s; + } + c = $.el('canvas'); + c.height = img.height; + c.width = img.width; + c.getContext('2d').drawImage(img, 0, 0, img.width, img.height); + data = atob(c.toDataURL().split(',')[1]); + l = data.length; + ui8a = new Uint8Array(l); + for (i = 0; 0 <= l ? i < l : i > l; 0 <= l ? i++ : i--) { + ui8a[i] = data.charCodeAt(i); + } + bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder)(); + bb.append(ui8a.buffer); + _this.url = url.createObjectURL(bb.getBlob('image/png')); + _this.el.style.backgroundImage = "url(" + _this.url + ")"; + console.log(_this.url); + return url.revokeObjectURL(fileUrl); + }); + return img.src = fileUrl; }; _Class.prototype.select = function() { diff --git a/changelog b/changelog index ec713707f..88dd9f129 100644 --- a/changelog +++ b/changelog @@ -3,6 +3,7 @@ master General performance improvements. Threads will now be updated instantly after posting through the QR. Your own posts will not count toward the unread count after posting through the QR. + QR thumbnails of high-res pictures will not slow down with anymore. - noface Add unique ID to filter. diff --git a/script.coffee b/script.coffee index 91840d0a7..e4fa51504 100644 --- a/script.coffee +++ b/script.coffee @@ -1268,14 +1268,54 @@ qr = qr.replies.push @ setFile: (@file) -> @el.title = file.name + $('label', @el).hidden = false if qr.spoiler if file.type is 'application/pdf' @el.style.backgroundImage = null return - $('label', @el).hidden = false if qr.spoiler url = window.URL or window.webkitURL url.revokeObjectURL @url - @url = url.createObjectURL file - @el.style.backgroundImage = "url(#{@url})" + + # Create a redimensioned thumbnail. + fileUrl = url.createObjectURL file + img = $.el 'img' + + $.on img, 'load', => + # Generate thumbnails only if they're really big. + # Resized pictures through canvases look like ass, + # so we generate thumbnails `s` times bigger then expected + # to avoid crappy resized quality. + s = 90*3 + if img.height < s or img.width < s + @url = fileUrl + @el.style.backgroundImage = "url(#{@url})" + return + if img.height <= img.width + img.width = s / img.height * img.width + img.height = s + else + img.height = s / img.width * img.height + img.width = s + c = $.el 'canvas' + c.height = img.height + c.width = img.width + c.getContext('2d').drawImage img, 0, 0, img.width, img.height + # Support for toBlob fucking when? + data = atob c.toDataURL().split(',')[1] + + # DataUrl to Binary code from Aeosynth's 4chan X repo + l = data.length + ui8a = new Uint8Array l + for i in [0...l] + ui8a[i] = data.charCodeAt i + bb = new (window.MozBlobBuilder or window.WebKitBlobBuilder)() + bb.append ui8a.buffer + + @url = url.createObjectURL bb.getBlob 'image/png' + @el.style.backgroundImage = "url(#{@url})" + console.log @url + url.revokeObjectURL fileUrl + + img.src = fileUrl select: -> qr.selected?.el.id = null qr.selected = @