0

I am creating a webpage that generates in line svg images and then allows the user to download them in various formats. (png,jpg,jpeg,svg) I have an exporting function to convert the images from inline svg to canvas as then canvas to dataURL for download. When I try exporting with Chrome, it takes time to shrink larger images down (7,000x10,000px) to the canvas because of Chrome's data cap. (FF doesn't have any issue and can shrink massive images in a fraction of the time that chrome can)

I need to create a loading progress bar for when the image is taking a while to populate and download from the canvas. I tried the solutions in this answer to no avail because I am using a objectURL created from a svg blob and not a image file on the server.

Is there a way to view the progress of an image load when setting the image src using an objectURL.

canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d',{alpha:false});

// creates a new blank image
var img = new Image();

// encode the svg to a string
var data = (new XMLSerializer()).serializeToString(svg);

// creates a blob from the encoded svg
 var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});

// creates an object url for the download
var url = DOMURL.createObjectURL(svgBlob);

// when the image is done being created and its loaded
img.onload = function(){ /* drawImage to canvas and save as dataURL*/ }

// load the image src using the objectURL
img.src = url;

Is there a way to read the progress of the image loading when the url is a objectURL not a image file?

Chadd Frasier
  • 153
  • 1
  • 9

1 Answers1

0

Short answer, there's no way I know of to do what you're asking. As you say, you're not downloading from a server, so there's no 'onprogress' event to hook into. You need something to provide regular alerts from inside the createObjectURL function, and it does not provide an event to hook into that it will fire 20 times during processing to give you a status.

What you could do instead is estimate how long it will take in Chrome, and provide an estimated status bar that way. If you know how big your canvas is, you can estimate how long it will take Chrome to generate your image based on its fixed data cap. If a 7Kx10K image takes x seconds, it should generally take that same time to generate every time, due to the fixed data cap, correct? Do a little math to figure out the seconds based on overall pixels. If it take 100 seconds to process (or whatever it takes), then that's 700,000 px / sec. Again, because of the fixed data cap, this value should remain the same until Chrome changes its data cap in a new version.

You could then provide a simulated progress bar that advances at that rate for how many px total you have. If you have 7M px, then it should take 10 seconds to advance the bar from 0 to 100% (based on my sample rate of 700Kpx/sec).

This is all based on Chrome having a fixed data cap; you can calculate a math rate against that based on the number of px you have to process.

HBlackorby
  • 1,308
  • 1
  • 11
  • 18
  • I thought of doing this instead of reading the data as it loads but since the image is so large, none of the DOM updates graphically until the image is loaded. So unfortunately the bar will not grow in size until the image is done loading. – Chadd Frasier Sep 12 '19 at 18:20
  • Can you call the function in a web worker or async so that you can run other processes (and update the dom) while it executes? That's one of the main purposes of web workers. – HBlackorby Sep 13 '19 at 15:20
  • I haven't thought of this, I will give it a go and report back. Thank you so much for your help. – Chadd Frasier Sep 13 '19 at 16:22
  • Sadly using workers will not solve my problem either. Workers are not a part of the node.js environment and cannot natively run the modules that I need. I will need to send an request to my server and run the canvas processing on the node server using npm canvas. Thanks for your help once more. – Chadd Frasier Sep 13 '19 at 20:28