2

I have an experimental application using Three.js, in which I am allowing the user to save a diagram he draws on a canvas element as a JPEG. I am doing so by using:

<a id="download" download="PathPlanner.jpg">Download as image</a>

function download() {
var dt = canvas.toDataURL('PathPlanner/jpeg');
this.href = dt;
}
document.getElementById('download').addEventListener('click', download, false);

while making sure that

preserveDrawingBuffer: true

This works fine, and the saved jpeg image may look something like this:

enter image description here

I am then experimenting with this package, which accepts an image and finds the shortest distance between two points following any particular line color. Path-from-image package uses jpeg-js to encode and decode images.

As far as I know the 0th and first bytes of a JPEG image are always 0xFF and 0xD8, However, I keep getting the following error on the saved .jpg image file:

Uncaught Error: SOI not found at constructor.parse

I am using the example code from path-from-image package to test it's functionality in my application. The code is:

        const fs = require('fs');
        const jpeg = require('jpeg-js');
        const PathFromImage = require('path-from-image');

        const redPointCoords = [0, -16];
        const bluePointCoords = [0, 0];

        const image = jpeg.decode(fs.readFileSync('Images/PathPlanner.jpg'), true);
        const pathFromImage = new PathFromImage({
            width: image.width,
            height: image.height,
            imageData: image.data,
            colorPatterns: [{ r: [128], g: [128], b: [128] }], // 
             description of the gray color
        });
        const path = pathFromImage.path(redPointCoords, bluePointCoords);
        console.log(path);

The error is pointing to const image = jpeg.decode(fs.readFileSync(''), true);

While the error is generated here:

        var fileMarker = readUint16();
        if (fileMarker != 0xFFD8) { // SOI (Start of Image)
            throw new Error("SOI not found");
        }

This is Line 598 in jpeg-js/lib/decoder.js.

The package works well with other images but not with the image I am allowing the user to save.

Any pointers on how to overcome this issue?

rrz0
  • 2,182
  • 5
  • 30
  • 65
  • 2
    The documentation about [`.toDataUrl()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL) says: _canvas.toDataURL(type, encoderOptions);_ . In your example of code `var dt = canvas.toDataURL('PathPlanner/jpeg');`, what does _'PathPlanner/jpeg'_ mean? – prisoner849 Nov 23 '17 at 07:27
  • @prisoner849, that was it! Excellent catch, overlooked that for a moment. Would happily accept your answer if you decided to write it down. – rrz0 Nov 23 '17 at 08:13
  • 2
    FYI: see https://stackoverflow.com/questions/30628064/how-to-toggle-preservedrawingbuffer-in-three-js/30647502#30647502 – WestLangley Nov 23 '17 at 15:20

1 Answers1

4

The documentation about .toDataURL() says: canvas.toDataURL(type, encoderOptions);. In your example of code,

var dt = canvas.toDataURL('PathPlanner/jpeg');` 

this method gets wrong mime-type, thus it produces PNG as default, which should be 'image/jpeg', and the result will be like that:

var dt = canvas.toDataURL('image/jpeg');
prisoner849
  • 16,894
  • 4
  • 34
  • 68