0

Hi I'm writing a function to break up a large image into individual smaller tiles, and save the tiles locally via Filesaver.js. However, for some reason, the for-loop keeps writing only the last tile in. For example, if I have a image and break it up into 4 blocks, and only decide to write out two blocks in the first row, both saved image tiles display the 2nd image tile.

I also write out the block number into the image name (TestImage_0.jpg & TestImage_1.jpg), but both tile image names are TestImage_1.jpg. I have no clue why!, even tried context.clearRect, but no success. Can someone please help me out here with this silly problem? Here is my function:

var canvas = document.createElement('canvas');

var TileWidthpx = parseInt(document.getElementById("HorizPPT").value);
var TileHeightpx = parseInt(document.getElementById("VertPPT").value);
canvas.setAttribute('width', TileWidthpx);
canvas.setAttribute('height', TileHeightpx);

for(var i = 0; i < 2; i++)
{   
    var context = canvas.getContext('2d');
    context.clearRect(0,0,canvas.width,canvas.height);
    context.drawImage(CoverageImg,i*TileWidthpx,0,TileWidthpx,TileHeightpx,0,0,TileWidthpx,TileHeightpx); 

    canvas.toBlob(function(blob){saveAs(blob,'TestImage_'+i+'.jpg');}, "image/jpg");

    alert('done: '+i);
}

Even though the alert displays the correct 'i' value of the loop... Please, anybody, is it some javascript async-problem that I'm missing (also converted the algorithm to a Promise, but that didn't solve anything)

PwC
  • 183
  • 3
  • 10

1 Answers1

0

So it was javascript's async functionality that made everything weird. Eventually got the tile generating algorithm correct by creating a repetitive function and adding delays (important) in the function, with help from here. Also had to pass the row and column values so that the correct template position could be generated. Here's my resulting code:

    var canvas = document.createElement('canvas');

    var TileWidthpx = parseInt(document.getElementById("HorizPPT").value);
    var TileHeightpx = parseInt(document.getElementById("VertPPT").value);
    canvas.setAttribute('width', TileWidthpx);
    canvas.setAttribute('height', TileHeightpx);

    var context = canvas.getContext('2d');      

    var col = 0; //variable for columns
    var row = 0;
    var ColCount = 2;
    var RowCount = 2;
    Loop(col,row,ColCount,RowCount);    //call delayed loop for first time
    function Loop (COL,ROW,ColCount,RowCount)   //repetitive function
    {    
        setTimeout(function () 
        {    
            context.beginPath();
            context.drawImage(CoverageImg,COL*TileWidthpx,ROW*TileHeightpx,TileWidthpx,TileHeightpx,0,0,TileWidthpx,TileHeightpx); 
            canvas.toBlob(function(blob){saveAs(blob,'TestImage_C'+COL+'_R'+ROW+'.png');}, "image/png");
            context.closePath();
            context.clearRect(0,0,canvas.width,canvas.height);   
            COL++;  

            if(COL == ColCount)
            {
                COL = 0;
                ROW++;
            }
            if(ROW < RowCount)                  
                Loop(COL,ROW,ColCount,RowCount);  //repeat function while below Col threshold    

        }.bind(this), 2000) //function delayed with 2 seconds*/
    }

Hope this helps whomever gets stuck with the same annoying problem...

Community
  • 1
  • 1
PwC
  • 183
  • 3
  • 10