Skip to content
This repository has been archived by the owner on Sep 29, 2020. It is now read-only.

Return watermarked image as JPEG #42

Open
davidquon opened this issue Mar 29, 2018 · 4 comments
Open

Return watermarked image as JPEG #42

davidquon opened this issue Mar 29, 2018 · 4 comments

Comments

@davidquon
Copy link

Kind of related to #34, the watermarked image is returned as a PNG image object even though the original object was a JPEG. Is there a way to return the watermarked image as a JPEG so EXIF data can be written to it?

@skliffmueller
Copy link
Contributor

skliffmueller commented Mar 30, 2018

I am having similar issues, as when jpegs get converted to png's, the compression is horrible.

return canvas.toDataURL();

That function should be designed to accept the following:
use the image source type when all images are the same
accept a user defined parameter to select image type
accept a user defined quality parameter
default to png if all else fails.

I will be working on a fork in the next few days.

API for reference
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL

Edit: This may not help the exif data issue, I do not think canvas retains that kind of information. But how I got around the exif issue is I just rotated the canvas accordingly based off exif-js library

Here is a snippet of code for reference:

dataURLtoFile(dataurl, filename) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while(n--){
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, {type:mime});
    }

    resetOrientation(fileData, fileName, orientation) {
        return new Promise((resolve, reject) => {
            var img = new Image();
            
            img.onload = () => {
                var width = img.width,
                    height = img.height,
                    canvas = document.createElement('canvas'),
                    ctx = canvas.getContext("2d");

                // set proper canvas dimensions before transform & export
                if (4 < orientation && orientation < 9) {
                    canvas.width = height;
                    canvas.height = width;
                } else {
                    canvas.width = width;
                    canvas.height = height;
                }

                // transform context before drawing image
                switch (orientation) {
                    case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
                    case 3: ctx.transform(-1, 0, 0, -1, width, height ); break;
                    case 4: ctx.transform(1, 0, 0, -1, 0, height ); break;
                    case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
                    case 6: ctx.transform(0, 1, -1, 0, height , 0); break;
                    case 7: ctx.transform(0, -1, -1, 0, height , width); break;
                    case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
                    default: break;
                }

                // draw image
                ctx.drawImage(img, 0, 0);

                // export base64
                let newFile = this.dataURLtoFile(canvas.toDataURL(), fileName);
                resolve(newFile);
            };

            img.src = URL.createObjectURL(fileData);
        })

    }
    rotateImages(file) {
        var fr = new FileReader();
        fr.onload = () => {
            let tags = EXIF.readFromBinaryFile(fr.result);
            this.resetOrientation(file.data, file.name, tags['Orientation']).then(newFile => {

            })
        };
        fr.readAsArrayBuffer(file.data);
    }

@davidquon
Copy link
Author

That function should be designed to accept the following:
use the image source type when all images are the same
accept a user defined parameter to select image type
accept a user defined quality parameter
default to png if all else fails.

Makes sense to me. 👍 @brianium - I'm not clear on how the options configuration works for watermark. Is there any documentation what configurations are accepted?

Edit: This may not help the exif data issue, I do not think canvas retains that kind of information. But how I got around the exif issue is I just rotated the canvas accordingly based off exif-js library

Once converted to a canvas the exif data will be lost unless saved and written back to the image file (if possible depending on the image type). Even if I save the exif data prior to watermarking I cannot write it back to the image file since a PNG is currently always being returned.

@davidquon
Copy link
Author

By the way thanks @skliffmueller as this was the line of code I was looking for and was alluding me. 🍻

return canvas.toDataURL();

@brianium
Copy link
Owner

brianium commented Apr 1, 2018

@davidquon the options parameter does not do much right now. Maybe I could do a better job documenting this, but the relevant documentation is here. For now the only property used is init which is a function that receives an Image before it loads. The relevant code is here.

My thought on using an options object was that it could grow to support other things if necessary :)

Let me know if I can answer anything else :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants