From 2bf417045e8915a9c58fb5c4cb018cc54df329d9 Mon Sep 17 00:00:00 2001
From: Karishma Chadha <kchadha@scratch.mit.edu>
Date: Sun, 22 Apr 2018 21:31:48 -0400
Subject: [PATCH] Add bitmap support to backdrop upload button.

---
 .../stage-selector/stage-selector.jsx         |  2 +-
 src/containers/stage-selector.jsx             | 42 +++++++++++++------
 2 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/src/components/stage-selector/stage-selector.jsx b/src/components/stage-selector/stage-selector.jsx
index d4b7e13ec..66fbc1fe9 100644
--- a/src/components/stage-selector/stage-selector.jsx
+++ b/src/components/stage-selector/stage-selector.jsx
@@ -86,7 +86,7 @@ const StageSelector = props => {
                         title: intl.formatMessage(messages.addBackdropFromFile),
                         img: fileUploadIcon,
                         onClick: onBackdropFileUploadClick,
-                        fileAccept: '.svg', // Bitmap coming soon
+                        fileAccept: '.svg, .png, .jpg, .jpeg', // Bitmap coming soon
                         fileChange: onBackdropFileUpload,
                         fileInput: fileInputRef
                     }, {
diff --git a/src/containers/stage-selector.jsx b/src/containers/stage-selector.jsx
index 9dd420a9b..bac150fe6 100644
--- a/src/containers/stage-selector.jsx
+++ b/src/containers/stage-selector.jsx
@@ -10,6 +10,8 @@ import StageSelectorComponent from '../components/stage-selector/stage-selector.
 
 import backdropLibraryContent from '../lib/libraries/backdrops.json';
 import costumeLibraryContent from '../lib/libraries/costumes.json';
+import {importBitmap} from 'scratch-svg-renderer';
+import log from '../lib/log.js';
 
 class StageSelector extends React.Component {
     constructor (props) {
@@ -63,7 +65,6 @@ class StageSelector extends React.Component {
             // if they choose
             thisFileInput.value = null;
             // Cache the image in storage
-            const backdropBuffer = reader.result;
             const storage = this.props.vm.runtime.storage;
             const fileType = thisFile.type; // check what the browser thinks this is
             // Only handling png and svg right now
@@ -75,26 +76,43 @@ class StageSelector extends React.Component {
             } else if (fileType === 'image/jpeg') {
                 backdropFormat = storage.DataFormat.JPG;
                 assetType = storage.AssetType.ImageBitmap;
-            } else {
+            } else if (fileType === 'image/png') {
                 backdropFormat = storage.DataFormat.PNG;
                 assetType = storage.AssetType.ImageBitmap;
             }
+            if (!backdropFormat) return;
 
-            const md5 = storage.builtinHelper.cache(
-                assetType, backdropFormat, new Uint8Array(backdropBuffer));
+            const addBackdropFromBuffer = (function (error, backdropBuffer) {
+                if (error) {
+                    log.warn(`An error occurred while trying to extract image data: ${error}`);
+                    return;
+                }
 
-            const md5Ext = `${md5}.${backdropFormat}`;
+                const md5 = storage.builtinHelper.cache(
+                    assetType, backdropFormat, backdropBuffer);
 
-            const vmBackdrop = {
-                name: 'backdrop1',
-                dataFormat: backdropFormat,
-                md5: `${md5Ext}`
-            };
+                const md5Ext = `${md5}.${backdropFormat}`;
 
-            this.props.vm.addBackdrop(md5Ext, vmBackdrop);
+                const vmBackdrop = {
+                    name: 'backdrop1',
+                    dataFormat: backdropFormat,
+                    md5: `${md5Ext}`
+                };
 
-            this.props.onActivateTab(COSTUMES_TAB_INDEX);
+                this.props.vm.addBackdrop(md5Ext, vmBackdrop);
+                this.props.onActivateTab(COSTUMES_TAB_INDEX);
+            }).bind(this);
 
+            if (backdropFormat === storage.DataFormat.SVG) {
+                // Must pass in file data as a Uint8Array,
+                // passing in an array buffer causes the sprite/costume
+                // thumbnails to not display because the data URI for the costume
+                // is invalid
+                addBackdropFromBuffer(null, new Uint8Array(reader.result));
+            } else {
+                // otherwise it's a bitmap
+                importBitmap(reader.result, addBackdropFromBuffer);
+            }
         };
         if (thisFileInput.files) {
             thisFile = thisFileInput.files[0];
-- 
GitLab