From df16ce481cf1c8a1aef37133d72f5794c56a5a8b Mon Sep 17 00:00:00 2001
From: Roman Nurik
Date: Fri, 26 Jul 2013 11:13:44 -0700
Subject: [PATCH] Under-the-hood improvements to Device Art Generator.
Use Canvas.toBlob with a polyfill, to avoid img src with massive data URLs, which causes some browsers to crash
Also change the resulting filename to be more appropriate, and make dragging-out to your desktop use this filename.
Change-Id: I13d8b4e119af8fecf567ecd6ccf3bb3e7b2d0fae
(cherry picked from commit 9da49f160612433e8ba562796ca5d6486ab48d83)
---
docs/html/distribute/promote/device-art.jd | 88 +++++++++++++++++++++++++-----
1 file changed, 73 insertions(+), 15 deletions(-)
diff --git a/docs/html/distribute/promote/device-art.jd b/docs/html/distribute/promote/device-art.jd
index 09a39417fe46..76def1ff8fdb 100644
--- a/docs/html/distribute/promote/device-art.jd
+++ b/docs/html/distribute/promote/device-art.jd
@@ -47,7 +47,9 @@ feature image or screenshots for your Google Play app listing.
-
No input image.
+
+
No input image.
@@ -143,6 +145,8 @@ feature image or screenshots for your Google Play app listing.
// Global variables
var g_currentImage;
var g_currentDevice;
+ var g_currentObjectURL;
+ var g_currentBlob;
// Global constants
var MSG_INVALID_INPUT_IMAGE = 'Invalid screenshot provided. Screenshots must be PNG files '
@@ -267,14 +271,15 @@ feature image or screenshots for your Google Play app listing.
return;
}
+ polyfillCanvasToBlob();
setupUI();
// Set up Chrome drag-out
$.event.props.push("dataTransfer");
document.body.addEventListener('dragstart', function(e) {
- var a = e.target;
- if (a.classList.contains('dragout')) {
- e.dataTransfer.setData('DownloadURL', a.dataset.downloadurl);
+ var target = e.target;
+ if (target.classList.contains('dragout')) {
+ e.dataTransfer.setData('DownloadURL', target.dataset.downloadurl);
}
}, false);
});
@@ -419,7 +424,7 @@ feature image or screenshots for your Google Play app listing.
ctx.translate(-h, 0);
ctx.drawImage(g_currentImage, 0, 0);
- loadImageFromUri(canvas.toDataURL(), function(img) {
+ loadImageFromUri(canvas.toDataURL('image/png'), function(img) {
g_currentImage = img;
createFrame();
});
@@ -459,10 +464,10 @@ feature image or screenshots for your Google Play app listing.
var resourceImages = {};
loadImageResources(resList, function(r) {
resourceImages = r;
- continuation_();
+ continueWithResources_();
});
- function continuation_() {
+ function continueWithResources_() {
var width = resourceImages['back'].naturalWidth;
var height = resourceImages['back'].naturalHeight;
var offset = port ? g_currentDevice.portOffset : g_currentDevice.landOffset;
@@ -486,17 +491,46 @@ feature image or screenshots for your Google Play app listing.
ctx.drawImage(resourceImages['fore'], 0, 0);
}
- var dataUrl = canvas.toDataURL();
+ window.URL = window.URL || window.webkitURL;
+ if (canvas.toBlob && window.URL.createObjectURL) {
+ if (g_currentObjectURL) {
+ window.URL.revokeObjectURL(g_currentObjectURL);
+ g_currentObjectURL = null;
+ }
+ if (g_currentBlob) {
+ if (g_currentBlob.close) {
+ g_currentBlob.close();
+ }
+ g_currentBlob = null;
+ }
+
+ canvas.toBlob(function(blob) {
+ if (!blob) {
+ continueWithFinalUrl_(canvas.toDataURL('image/png'));
+ return;
+ }
+ g_currentBlob = blob;
+ g_currentObjectURL = window.URL.createObjectURL(blob);
+ continueWithFinalUrl_(g_currentObjectURL);
+ }, 'image/png');
+ } else {
+ continueWithFinalUrl_(canvas.toDataURL('image/png'));
+ }
+ }
+
+ function continueWithFinalUrl_(imageUrl) {
var filename = g_currentFilename
- ? ('framed_' + g_currentFilename)
+ ? g_currentFilename.replace(/^(.+?)(\.\w+)?$/, '$1_framed.png')
: 'framed_screenshot.png';
var $link = $('')
.attr('download', filename)
- .attr('href', dataUrl)
- .attr('draggable', true)
- .attr('data-downloadurl', ['image/png', filename, dataUrl].join(':'))
- .append($('
').attr('src', dataUrl))
+ .attr('href', imageUrl)
+ .append($('
')
+ .addClass('dragout')
+ .attr('src', imageUrl)
+ .attr('draggable', true)
+ .attr('data-downloadurl', ['image/png', filename, imageUrl].join(':')))
.appendTo($('#output').empty());
$('#frame-customizations').show();
@@ -566,14 +600,14 @@ feature image or screenshots for your Google Play app listing.
var file = null;
for (var i = 0; i < fileList.length; i++) {
- if (fileList[i].type.toLowerCase().match(/^image\/png/)) {
+ if (fileList[i].type.toLowerCase().match(/^image\/(png|jpeg|jpg)/)) {
file = fileList[i];
break;
}
}
if (!file) {
- alert('Please use a valid screenshot file (PNG format).');
+ alert('Please use a valid screenshot file (PNG or JPEG format).');
callback(null);
return;
}
@@ -609,4 +643,28 @@ feature image or screenshots for your Google Play app listing.
fileReader.readAsDataURL(file);
}
+
+ /**
+ * Adds a simple version of Canvas.toBlob if toBlob isn't available.
+ */
+ function polyfillCanvasToBlob() {
+ if (!HTMLCanvasElement.prototype.toBlob && window.Blob) {
+ HTMLCanvasElement.prototype.toBlob = function(callback, mimeType, quality) {
+ if (typeof callback != 'function') {
+ throw new TypeError('Function expected');
+ }
+ var dataURL = this.toDataURL(mimeType, quality);
+ mimeType = dataURL.split(';')[0].split(':')[1];
+ var bs = window.atob(dataURL.split(',')[1]);
+ if (dataURL == 'data:,' || !bs.length) {
+ callback(null);
+ return;
+ }
+ for (var ui8arr = new Uint8Array(bs.length), i = 0; i < bs.length; ++i) {
+ ui8arr[i] = bs.charCodeAt(i);
+ }
+ callback(new Blob([ui8arr.buffer /* req'd for Safari */ || ui8arr], {type: mimeType}));
+ };
+ }
+ }
--
2.11.0