locked
Load big image fail after load several times in Metro app and IE10 (code is attached)

    Question


  • Hi, Im using metro app to develop an image loading system. However, by using javascript to load image will cause a very serious problem. 

    Here is a test record I made:

    Loaded count

    Metro.8250

    IE10

    Chrome18

    9999x7029

    2

    error

    30+

    8000x5623

    3

    1

    30+

    7000x4920

    4

    1

    30+

    5000x3514

    6

    5

    30+

    4000x2811

    11

    11

    30+

    As shown above, the system will fail after loading an image with dimensions '9999x7029' two times, three times in 8000x5623... 

    I will list two load implementation in both metro app and IE10:

    1. Here is my code tested in metro app:

    default.js

    // For an introduction to the Blank template, see the following documentation:
    // http://go.microsoft.com/fwlink/?LinkId=232509
    (function () {
        "use strict";
    
        var app = WinJS.Application;
        app.imgLoaded = false;
        app.ctx = null;
        app.canW = null;
        app.canH = null;
    
        app.clear = function () {
            if (app.ctx && app.canW && app.canH) {
                id('output').innerHTML = 'clearing...';
                app.ctx.clearRect(0, 0, app.canW, app.canH);
                var mainCanvas = id('mainCanvas');
                mainCanvas.width = 0;
                mainCanvas.height = 0;
                app.imgLoaded = false;
                id('output').innerHTML = 'cleared';
            }
        };
        var id = function (ele) {
            return document.getElementById(ele);
        };
        
        app.onactivated = function (eventObject) {
            if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
                if (eventObject.detail.previousExecutionState !== Windows.ApplicationModel.Activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize 
                    // your application here.
    
                    id('picker').onclick = function () {
    
                        app.clear();
    
                        var picker = new Windows.Storage.Pickers.FileOpenPicker();
                        picker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
                        picker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
                        picker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg", ".bmp"]);
    
                        picker.pickSingleFileAsync().then(function (file) {
                            if (!file) {
                                console.log('file is not got...');
                                return;
                            }
    
                            
                            var blob = window.URL.createObjectURL(file, false);
                            var canvasImage = document.createElement('img');
                            canvasImage.onerror = function () {
                                id('output').innerHTML = 'img load error...';
                            };
                            canvasImage.onload = function () {
                                id('output').innerHTML = 'img loaded...';
    
                                console.log('onload starts at: ' + (new Date()).valueOf());
                                console.log(canvasImage.complete);
    
                                var mainCanvas = id('mainCanvas');
                                var context = mainCanvas.getContext("2d");
                                app.ctx = context;
                                mainCanvas.width = canvasImage.naturalWidth;
                                mainCanvas.height = canvasImage.naturalHeight;
    
                                app.canW = mainCanvas.width;
                                app.canH = mainCanvas.height;
    
                                id('output').innerHTML = 'drawing img to canvas...';
    
                                context.drawImage(this, 0, 0, mainCanvas.width, mainCanvas.height);
                                console.log('draw canvas finish at: ' + (new Date()).valueOf());
                                
                                id('output').innerHTML = 'complete drawing img to canvas...';
    
                                app.imgLoaded = true;
                                console.log('======================================================');
    
                                window.URL.revokeObjectURL(blob);
                                canvasImage = undefined;
                                id('output').innerHTML = '';
                            };
                            
                            id('output').innerHTML = 'loading img to blob...';
                            canvasImage.src = blob;
                            console.log('src is set at: ' + (new Date()).valueOf());
                        });
                    };
                } else {
                    // TODO: This application has been reactivated from suspension. 
                    // Restore application state here.
                }
                WinJS.UI.processAll();
            }
        };
    
        app.oncheckpoint = function (eventObject) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the 
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // eventObject.setPromise(). 
        };
    
        app.start();
    })();

    default.html

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>imgLoadTest</title>
    
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet">
        <script src="//Microsoft.WinJS.0.6/js/base.js"></script>
        <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>
    
        <!-- imgLoadTest references -->
        <link href="/css/default.css" rel="stylesheet">
        <script src="/js/default.js"></script>
    </head>
    <body style="">
        <button id="picker" style="border: 1px solid white">open</button>
        <p id="output"></p>
        <canvas id="mainCanvas"></canvas>
    </body>
    </html>

    2.Below is my code tested in IE 10:

    default.html

    <!DOCTYPE html>
    <html>
    <body>
    	<button onclick='reloadImg();'>重新载入</button>
    	<p id='output'></p>
    	<div id='img'></div>
    <script type="text/javascript">
    	function reloadImg(){
    		document.getElementById('img').innerHTML = '';
    		var img = document.createElement('img');
    		img.onload = function(){
    			document.getElementById('output').innerHTML = 'img loaded!';
    			document.getElementById('img').appendChild(img);
    		};
    		img.onerror = function(){
    			document.getElementById('output').innerHTML = 'img load error!';
    		};
    		function random(){
    			return Math.random() * (new Date()).valueOf();
    		}
    		document.getElementById('output').innerHTML = 'loading img ...';
    		img.src = '9999x7029.jpg?time=' + random();	// 9999
    		//img.src = '8000x5623.jpg?time=' + random();	// 8000
    		//img.src = '7000x4920.jpg?time=' + random();	// 7000
    		//img.src = '5000x3514.jpg?time=' + random();	// 5000
    		//img.src = '4000x2811.jpg?time=' + random();	// 4000
    		
    	}
    	
    </script>
    
    </body>
    </html>

    Is there any improvement that I can apply? 

    Thanks!


    • Edited by Bin.Sun Thursday, April 5, 2012 9:02 AM
    Thursday, April 5, 2012 9:00 AM

Answers

  • Hi Bin Sun - this issue should be fixed in the next version.  I am sorry for the very long delay in responding.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator

    • Marked as answer by Bob_Bao Monday, May 7, 2012 10:18 AM
    Wednesday, May 2, 2012 4:27 PM
    Moderator

All replies

  • Hin Bin.Sun - can you send the application (as well as the images) to me at msmall at Microsoft.com, please?  I would put all of this in myself but we're handling a lot of questions so it would be preferable to get an already-made application.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator

    Friday, April 6, 2012 5:24 PM
    Moderator
  • What is the error message you are receiving on IE10? (for the first entry in your result summary table)

    For the other results where it is failing are getting any errors or exceptions?

    Friday, April 6, 2012 6:28 PM
  • I often do this "setTimeout(function (){

    context.drawImage(this, 0, 0, mainCanvas.width, mainCanvas.height);

    }, 100);".

    It just a workaround.


    • Edited by Haaaaappy Monday, April 9, 2012 2:50 AM
    Monday, April 9, 2012 2:50 AM
  • Hi Matt Small,  thanks for your attention. I have sent an email to you, please have a check. 


    sun

    Monday, April 9, 2012 2:58 AM
  • I used img.onerror to catch error, however, there is no error message for that. 

    For the rest in metro, the img loads very slow, and become slower each time, and the same situation in IE10...


    sun

    Monday, April 9, 2012 3:03 AM
  • Hi Bin Sun - this issue should be fixed in the next version.  I am sorry for the very long delay in responding.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator

    • Marked as answer by Bob_Bao Monday, May 7, 2012 10:18 AM
    Wednesday, May 2, 2012 4:27 PM
    Moderator