I recently crafted some code that meets your specified requirements. Here is a breakdown of what I implemented:
- Loaded a local image using FileReader and attached a listener to its
onload
event.
- In the
onload
listener, instantiated an "Image" object with new Image()
, and set the "src" attribute to the loaded image's source (in Data URL format).
- Created a "Canvas" element and rendered the image on this canvas.
- Utilized Canvas.toDataURL() to retrieve the converted image data in base64 format.
- Sent the image data to the server for processing.
Upon drawing an image onto the canvas, invoking Canvas.toDataURL()
returns the canvas content in a Data URL string. It's important to note that this represents the canvas data and not the original image data. For instance, if the image size is 100 x 100 but the canvas dimensions are 50 x 50, calling this function will yield an image of 50 x 50 pixels. To obtain a full-size image, you must resize the canvas accordingly.
This function requires two parameters:
canvas.toDataURL(type, encoderOptions);
- type - A DOMString specifying the image format. By default, the type is image/png. In your scenario, remember to set it as "image/jpeg".
- encoderOptions - A number between 0 and 1 indicating the image quality when the type is image/jpeg or image/webp.
Below is my TypeScript implementation of the "preview and upload" function for your reference:
preview(input: HTMLInputElement) {
if (input.files.length) {
let reader = new FileReader();
reader.onload = (e) => {
if (!this.img) {
this.img = new Image();
}
this.img.src = (e.target as any).result;
this.img.onload = () => {
// omitted code for 'dx', 'dy', 'width', 'height' adjustments
let ctx = <CanvasRenderingContext2D>this.canvas.nativeElement.getContext('2d');
ctx.drawImage(this.img, dx, dy, width, height);
let dataUrl = (<HTMLCanvasElement>this.canvas.nativeElement).toDataURL('image/jpeg', 0.7);
this.uploadService.upload(dataUrl).then((resp: any) => {
if (resp.key) {
this.asset.image = resp.key;
}
});
};
}
reader.readAsDataURL(input.files[0]);
}
}
The variables dx, dx, width, height
have been left out from the above snippet, as they are used for adjusting the image position (primarily for clipping purposes).
Here is a JavaScript example:
function _elm(id) {
return document.getElementById(id);
}
_elm('fileInput').onchange= function(event) {
if (event.target.files.length) {
var fileReader = new FileReader();
fileReader.onload = function(event) {
var img = new Image();
img.src = event.target.result;
_elm('sizeRaw').innerText = '+ data-url size ' + event.target.result.length;
img.onload = function() {
var canvas = _elm('canvas');
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0, 200, 200);
var dataUrl = canvas.toDataURL('image/jpeg', 0.5);
_elm('output').innerText = dataUrl;
_elm('sizeNew').innerText = '+ data-url size ' + dataUrl.length;
}
};
fileReader.readAsDataURL(event.target.files[0]);
}
};
#canvas {
border: 1px solid blue;
}
#output {
word-break: break-all;
}
<h3>Input file <span id="sizeRaw"></span>: </h3>
<input id="fileInput" type="file" accept="image/*">
<h3>Canvas</h3>
<div>
<canvas id="canvas" width="200" height="200"></canvas>
</div>
<h3>Output <span id="sizeNew"></span>: </h3>
<div id="output">
</div>