The question on a single line:
Is there a toDataURL method working on a <IMG> element?
Most of the people seem to be interested in how to get an IMG from a CANVAS, but I need the opposite.
Why? I need to use the toDataURL() method on the IMG.
So, this is the pseudo code that I wish existed in reality:
var img = document.getElementById('myImage');
var canvas = img.getCanvasFromImage();
var dataURL = canvas.toDataURL();
Is there already a method, or a workaround (e.g. creating an empty canvas, copying the IMG on top, etc.) to do the getCanvasFromImage? I couldn't find one.
Some more details WHY, but there is no need to read further. I am using the VIDEO tag to get the camera stream, and when the user clicks a button, I copy the CANVAS to the IMG.
But since I do not want to show the whole picture while taking a photo (I want it to be consistent over different devices, regardless of the camera resolution, keeping a 16:9 aspect ratio), I only show a portion of the image using object-fit: cover; .
So, now I have a "partial" image, but if I do a toDataURL on the canvas I have, it gives me the WHOLE picture, regardless of the "object-fit" value.
If this is not clear, no problem :) I only need a "toDataURL" method working on a <IMG> element :)
HTMLImageElement.prototype.getCanvasFromImage = function(){
const canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0);
return canvas;
};
const img = document.getElementById('myImage');
img.onload = () => {
const canvas = img.getCanvasFromImage();
const dataURL = canvas.toDataURL();
console.log(dataURL);
}
<img id="myImage" crossorigin="anonymous" src="https://dl.dropbox.com/s/zpoxft30lzrr5mg/20201012_102150.jpg" />
Its work, but please READ THIS. Better way is create pure function and pass image as argument:
function getCanvasFromImage(image) {
const canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
return canvas;
}
Related
i am a newbie to programming,
I have an HTML code for displaying base64 image the image is dynamic link, always come with different sizes
I need to resize that image and create preview mode with smaller image with an aspect ratio
ex:
my original image on html are 600x300 I need to preview it 300x150
my original image HTML are 1000x500 I need to preview 500x250
I have a javascript for resizing but can't figure out how to get image base64 from my HTML code
Please who can give me some help on these to archive my goal
I cant paste HTMl code here because is to long please check HTMl on codepin
https://codepen.io/Gilavani/pen/JjLXBOb
function resizedataURL(datas, wantedWidth, wantedHeight)
{
// We create an image to receive the Data URI
var img = document.createElement('img');
// When the event "onload" is triggered we can resize the image.
img.onload = function()
{
// We create a canvas and get its context.
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// We set the dimensions at the wanted size.
canvas.width = wantedWidth;
canvas.height = wantedHeight;
// We resize the image with the canvas method drawImage();
ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);
var dataURI = canvas.toDataURL();
/////////////////////////////////////////
// Use and treat your Data URI here !! //
/////////////////////////////////////////
};
// We put the Data URI in the image's src attribute
img.src = datas;
}
Thanks you in Advice
Best Regards
let srcImg = document.getElementById("orignal").src;
let prev = document.getElementById("preview");
function resizedataURL(datas, wantedWidth, wantedHeight)
{
prev.src = datas;
prev.onload = function()
{
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = wantedWidth;
canvas.height = wantedHeight;
ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);
prev.src = canvas.toDataURL();
};
}
resizedataURL(srcImg, 150,150);
<html>
<body>
<img id="orignal" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAAXNSR0IArs4c6QAAFSpJREFUeF7tnTuLZcUWgGtAZJykYRR0EAykwcBAEDM18h+YGPiIBEFREMxE8fEDBPGBgpEPMHByYzWbxEyh6UhnDHTAZJysZZ+Z3XP69Dm9a+9aVbUe3yTXvl2Ptb611nf3PnPuveeuXLlydPHixXT+/PnEHwhAAAIaCdy8eTNdv349nTs8PDwa/mF/fz/t7e1pjJWYIACBwAT+/fffdHBwkIYHq3NXr149unDhwurfQFqBu4LUIaCQwCirwU03bty4JaxLly6l9V/wpKWwcoQEgWAENp107dq1O8IaWCCtYB1BuhBQSmCbi04JC2kprR5hQSAQgV0PTluFhbQCdQapQkAZgbPe8nYKC2kpqyLhQCAAgamPpM4UFtIK0CGkCAElBKZkNYQ5KSykpaSahAEBxwRyZJUtLKTluFNIDQKdCeTKapawkFbnqnI9BBwSmCOr2cJCWg47hpQg0InAXFktEhbS6lRdroWAIwJLZLVYWEjLUeeQCgQaE1gqqyJhIa3GVeY6CDggUCKrYmEhLQcdRAoQaESgVFYiwkJajarNNRAwTEBCVmLCQlqGO4nQIVCZgJSsRIWFtCpXneMhYJCApKzEhYW0DHYUIUOgEgFpWVURFtKqVH2OhYAhAjVkVU1YSMtQZxEqBIQJ1JJVVWEhLeEu4DgIGCBQU1bVhYW0DHQYIUJAiEBtWTURFtIS6gaOgYBiAi1k1UxYSEtxpxEaBAoJtJJVU2EhrcKuYDsEFBJoKavmwkJaCjuOkCCwkEBrWXURFtJa2B1sg4AiAj1k1U1YSEtR5xEKBGYS6CWrrsJCWjO7hOUQUECgp6y6CwtpKehAQoBAJoHeslIhLKSV2S0sg0BHAhpkpUZYSKtjJ3I1BCYIaJGVKmEhLeYGAvoIaJKVOmEhLX0NS0RxCWiTlUphIa24A0LmegholJVaYSEtPY1LJPEIaJWVamEhrXiDQsb9CWiWlXphIa3+DUwEcQhol5UJYSGtOANDpv0IWJCVGWEhrX6NzM3+CViRlSlhIS3/g0OG7QlYkpU5YSGt9g3NjX4JWJOVSWEhLb8DRGbtCFiUlVlhIa12jc1N/ghYlZVpYSEtf4NERvUJWJaVeWEhrfoNzg1+CFiXlQthIS0/A0Um9Qh4kJUbYSGteo3OyfYJeJGVK2EhLfuDRQbyBDzJyp2wkJZ8w3OiXQLeZOVSWEjL7oARuRwBj7JyKyykJdf4nGSPgFdZuRYW0rI3aERcTsCzrNwLC2mVDwAn2CHgXVYhhIW07AwckS4nEEFWYYSFtJYPAjv1E4giq1DCQlr6B48I5xOIJKtwwkJa8weCHXoJRJNVSGEhLb0DSGT5BCLKKqywkFb+YLBSH4GosgotLKSlbxCJaJpAZFmFFxbSmh4QVughEF1WCOt2L9IIeoaSSLYToEdvcbl27Vo6d/Xq1aNLly6F7hUaInT5VSdPb94pD8Jaa1UaQ/XchgyOnjxZdoS1MQY0SEgvqEyaXjxdFoS1pVVpFJXzGyooenB7uRHWjjGgYUL5QVWy9N7uciCsM1qVxlE1xyGCoefOLjPCmhgDGiiEJ1QkSa9NlwFhTTNKNFIGJJYUEaDH8vAhrDxOSCuTE8vmE0BW+cwQVj4rpDWDFUvzCCCrPE7jKoQ1jxfSmsmL5bsJIKv53YGw5jNDWguYseUkAWS1rCMQ1jJuSGshN7YleqegCRBWATz+U7IAXtCt9ExZ4RFWGT/+07KQX6TtyKq82girnCHSEmDo/QhkJVNhhCXDEWkJcfR4DLKSqyrCkmOJtARZejkKWclWEmHJ8kRawjwtH4es5KuHsOSZIq0KTK0diazqVAxh1eGKtCpxtXAssqpXJYRVjy3SqshW69HIqm5lEFZdvkirMl9NxyOr+tVAWPUZI60GjHtfgazaVABhteGMtBpx7nENsmpHHWG1Y420GrJudRWyakX61j0Iqy1vpNWYd83rkFVNutvPRljtmSOtDsylr0RW0kTzzkNYeZzEV9Hw4kibHUjtmqE+dRHC6seeJ62O7JdejayWkpPZh7BkOC4+hQFYjK75RmrVHDlPWP2Rn46AQdBYlZMxUSMdNeIJS0cdeD1UUodtYSArPcVBWHpqgbQU1WIMBVnpKgrC0lUPpKWoHshKUTFuh4Kw9NUEaSmoCbJSUIQtISAsnXVBWh3rgqw6wp+4GmHprQ3S6lAbZNUB+owrEdYMWD2WMkDtqMO6HeulNyGspeQa7mOQ6sOGcX3GEjcgLAmKDc5goOpBhm09ttInIyxpohXPY7Dk4cJUnmnNExFWTboVzmbA5KDCUo5lq5MQVivSgvcwaOUwYVjOsMcJCKsHdYE7GbjlEGG3nF3vnQirdwUK7mfw5sOD2XxmmnYgLE3VWBALA5gPDVb5rLSuRFhaKzMjLgZxGhaMphlZWIGwLFQpI0YGcjck2GQ0kJElCMtIoXLCZDBPU4JJTufYWYOw7NQqK1IG9A4mWGS1jKlFCMtUufKCZVAT/0sXea1ibhXCMleyvIAjSyty7nndYXcVwrJbu8nIIw5uxJwnG8HRAoTlqJjbUok0wJFydd62O9NDWAEqH2GQI+QYoFUnU0RYk4h8LPA80J5z89F9clkgLDmW6k/yONgec1LfSB0DRFgd4fe42tOAe8qlRy9YvBNhWaxaYcweBt1DDoVlDLkdYYUsu+0vViKroE2bUkJYcWtv8tvgyCpwwyKs2MUfsrckAEux0ll1CPCEVYerqVMtiMBCjKaKbjRYhGW0cNJhaxaC5tik68B5ZxNAWHTIMQGNYtAYEy3TjwDC6sde5c2aBKEpFpXFChgUwgpY9KmUNYhCQwxTnPh9ewIIqz1zEzf2FEbPu00UJ3CQCCtw8adS7yGOHndOceD3egggLD21UBlJS4G0vEslbIKaJICwJhGxoIVIWtxBJe0TQFj2a9gkg5pCqXl2Ezhc0owAwmqG2v5FNcRS40z7pMlgFwGERW/MIiApGMmzZiXBYrMEEJbZ0vULXEI0Emf0I8DNvQggrF7kjd9bIpySvcaxEX4hAYRVCDDy9iXiWbInMmNyP0kAYdERRQTmCGjO2qKg2OyWAMJyW9p2ieWIKGdNu4i5ySoBhGW1csriPktIyEpZsQyHg7AMF09b6NvEhKy0Vcl2PAjLdv3URb8uqCG4g4ODtL+/n/b29tTFSkD2CCAsezVTH/EorSFQZKW+XKYCRFimymUjWIRlo04Wo0RYFqumOGZeCRUXx0FoCMtBEbWkwIfuWirhNw6E5be2TTPjaw1NcYe9DGGFLb1c4jlfXchZIxcRJ3klgLC8VrZRXnNENGdto/C5xhgBhGWsYJrCXSKgJXs05UwsfQkgrL78zd5eIp6SvWaBEbgIAYQlgjHWIRLCkTgjFnWyHQggLPpgFgFJ0UieNSsJFpslgLDMlq594DUEU+PM9mS4sRUBhNWKtPF7aoql5tnGsRP+BgGERUtMEmghlBZ3TCbKAvUEEJb6EvUNsKVIWt7Vlyq3LyWAsJaSC7Cvh0B63BmglG5SRFhuSimbSE9x9LxbliKnSRNAWNJEHZynQRgaYnBQSncpICx3JS1LSJMoNMVSRpXdUgQQlhRJB+doFITGmByU2mwKCMts6WQD1ywGzbHJVoHTpgggrClCAX5vQQgWYgzQKt1TRFjdS9A3AEsisBRr36r6vR1h+a3tZGYWBWAx5slCsCCbAMLKRuVroeXBtxy7ry5qnw3Cas+8+40eBt5DDt0bwWAACMtg0UpC9jTonnIpqWmkvQgrULU9DrjHnAK15OxUEdZsZDY3eB5sz7nZ7LZ6USOsemzVnBxhoCPkqKahOgaCsDrCb3F1pEGOlGuL3tF4B8LSWBWhmCIOcMSchdrFxDEIy0SZ5gcZeXAj5z6/U2ztQFi26pUVLQObEgyyWsXcIoRlrmRnB8yg3uEDC2fNzf+Rqq+CMqCn6wkTXz3OE5aTejKYuwsJGydNzhOWj0IykNN1hNE0IwsreMKyUKUzYmQQ8wsIq3xWWlciLK2VyYiLAcyAtLEEZvOZadqBsDRVY0YsDN4MWEhrOSxlOxGWsoLkhIOsciidvQaG5Qx7nICwelAvuJNBK4DHk5YcvE4nIaxO4Jdci6yWUONJS55avxMRVj/2s25GVrNwzVoM21m4ui5GWF3x513OQOVxKlkF4xJ67fYirHasF93EIC3CtmgTrBdha7oJYTXFPe8yBmgeL4nVMJegWO8MhFWPbdHJDE4RvqLNsC/CV3UzwqqKd9nhDMwybpK7qIEkTbmzEJYcS5GTGBQRjCKHUAsRjKKHICxRnGWHMSBl/GrspiY1qC4/E2EtZye6k8EQxSl6GLURxVl0GMIqwiezmYGQ4VjzFGpUk27+2Qgrn1WVlQxCFaxVDqVWVbDOOhRhzcIlu5gBkOXZ4jRq1oLy7jsQVif+NH4n8ALXUjsBiAuPQFgLwZVso+FL6OnYSw371AFhNeZOozcGXvE6alkR7o6jEVZD5jR4Q9iNrqKmjUDfvgZhNeJNYzcC3eEaatsOOsJqwJqGbgC58xXUuE0BEFZlzjRyZcCKjqfW9YuBsCoypoErwlV6NDWvWxiEVYkvjVsJrIFjqX29IiGsCmxp2ApQjR1JD9QpGMIS5kqjCgM1fBy9IF88hCXIlAYVhOnkKHpCtpAIS4gnjSkE0uEx9IZcURGWAEsaUgCi8yPoEZkCI6xCjjRiIcBA2+mV8mIjrAKGNGABvKBb6ZmywiOshfxovIXg2JboneVNgLAWsKPhFkBjywkC9NCyhkBYM7nRaDOBsXwnAXppfnMgrBnMaLAZsFiaRYCeysJ0vAhhZfKisTJBsWw2AXorHxnCymBFQ2VAYkkRAXosDx/CmuBEI+U1EqvKCdBr0wwR1hmMaKDpBmKFLAF67myeCGsHHxpHdhA5LZ8AvbebFcLawoaGyR8uVtYhQA9u54qwNrjQKHUGkFPnE6AXTzNDWGtMaJD5Q8WOugToyZN8EdZtHjRG3cHj9OUE6M077BBWSvyXUZfPEjsbEUBat0CHFxaN0GjiuKaYAL0aXFg0QPEMcUBjAtF7NuwTVvTCN54zrhMkELl3QworcsEF54ajOhKI2sPhhBW10B1ni6srEYjYy6GEFbHAlWaFY5UQiNbTYYQVrbBK5okwGhCI1NshhBWpoA3mgysUEojS4+6FFaWQCmeIkBoTiNDrroUVoYCNZ4LrlBPw3vNuheW9cMrnhvA6EvDc+y6F5blgHeeAqw0R8DoD7oTltVCGZoVQlRDwOAuuhOWxQEp6nzCMEvA2E26E5a0wRueDsBUS8DQbLoTlqSAK+52QHBDwMiPmheWlEA5mghSUE/AwK6aF5aEAynuc8JwRsD4zZoVlHbyzOSAdQwQsz45JYVkGbqivCdUxAaszZE5YVkE77n1SM0rA4iyZEpZFwEZ7mbCDELA2U2aEZQ1skH4nTQcELM2WCWFZAuqgf0khIAErM6ZeWFZABuxxUnZGwMKsqRaWBYDOepZ0ghPQPnNqhaUdXPC+Jn3HBDTPnkphaQbmuE9JDQLHBLTOoDphaQVFL0MgGgGNs6hKWBoBRWtS8oXAOgFtM6lGWNrA0LYQgMAtAppmU4WwNAGhSSEAgdMEtMxod2FpAUGTQgACZxPQMKtdhaUBAE0KAQjkE+g9s92E1Tvx/BKxEgIQ0PJBfBdhISsGAAK2CfSa4ebC6pWo7fYgegjoI9BjlpsKq0eC+spMRBDwQ6D1TDcTVuvE/LQEmUBAN4GWs91EWC0T0l1aooOATwKtZry6sFol4rMNyAoCdgi0mPWqwmqRgJ1yEikE/BOoPfPVhFU7cP+lJ0MI2CRQc/arCKtmwDZLSNQQiEWglgPEhVUr0FjlJlsI2CdQwwWiwqoRoP2ykQEE4hKQdoKYsKQDi1tiMoeALwKSbhARlmRAvkpFNhCAwEBAyhHFwpIKhLJCAAK+CUi4okhYEgH4LhHZQQAC6wRKnbFYWKUXU0YIQCAmgRJ3LBJWyYUxS0TWEICAxJPWbGEhKxoPAhCQILDEJbOEteQCicQ4AwIQKCPwyy+/pKeeemp1yGOPPZa+//779Mgjjxwf+uGHH6Z333139fPPP/+cnnzyyePfffvtt+mFF15Y/fzNN9+k559/fjKYf/75Z7Xuxx9/3Lpv/czh7tdffz3t7e2t1v7+++/pueeeS7/++mt65ZVX0kcffZTuueee1e+yhYWsJmvEAgioJDAI4I033kgff/zxSlKDLL7++uvVv957771pkNkgjeHn33777fifh9+t7x2SWz9nV7L//fdfevPNN9PTTz+9ktYooE8//XQlws0zX3311fTaa6+lZ555Jt19993He5999tkT52QLC1mp7EOCgsAiApsCG2Q1/HnnnXfSKJsXX3xxJZdBYj/99NPxU86w9uGHH856yhqD2xTYtjMfeOCB9Pjjj6ejo6P09ttvH8t1kOkg1/Epa/IJC1kt6gk2QUAtgXVhDEGuPw1tymVdZsPa8ee33nprtW/4M8pk88ltBHCWINfPHJ7efvjhh/Tdd9+tXlk3n/6Gn88UFrJS23MEBoHZBNY/Gxo/p9p8ohoFMj5FbT5RDVI6PDw88TQ2vPo98cQTp14Xx7O/+OKL9MEHH6z2bJ4//Lx+5vCZ15dffpk+++yzdP/9969eH9977730ySefrAS2U1jIanY/sAECJgisf6Y0vIYNT0rjK+AcYQ1r1yW46wP5UVwPPvjgSlpnSXB4Bfzqq6/Syy+/nB599NH0119/TQsLWZnoO4KEwGICm6924wfkua+E49PSKLg///zzxN/mbQa2/sH+8PQ0/Fl/4hp/Htd9/vnn6fr16+nvv/9enTv+BcGpJyxktbgH2AgBEwS2SWl8Bdz2ofv4CrjtdW4QzPA3fMPr20svvbTzw/j1z80uX758/Fq5eeb6K+Bdd921+kxreH0d/oZx+GrDCWEhKxP9RpAQmEVg80PvUTLjd7GWfq1h/K7V8KR03333HX+G9dBDD534IH9cN7x2jl9zGL8eMSSy/lWJdZkOX2sYZDjIdPye1rGwLly4kA4ODtL+/v7xF7hmUWExBCCglsD6F0eHIDe/HDr3i6OjhIavPoyvdut/Szjcsf7F0fUP3YffnfVl1M0vjr7//vvpjz/+WLnpxo0b6dzh4eHR8L6IrNT2G4FBIDSB8e3v4sWL6dyVK1eOhn84f/58aCgkDwEI6CVw8+bN1Qfx/wPviqgmNjzArwAAAABJRU5ErkJggg==">
<h2>Preview</h2>
<img id="preview" src="#">
</body>
</html>
I'm converting images to base64 using canvas. What i need to do is convert those images and then show the result to the user (original image and base64 version). Everything works as expected with small images, but when i try to convert large images (>3MB) and the conversion time increases, the base64 version is empty.
This might be is caused because the result is shown before the toDataURL() function is completed.
I need to show the result after all the needed processing has ended, for testing purposes.
Here's my code:
var convertToBase64 = function(url, callback)
{
var image = new Image();
image.onload = function ()
{
//create canvas and draw image...
var imageData = canvas.toDataURL('image/png');
callback(imageData);
};
image.src = url;
};
convertToBase64('img/circle.png', function(imageData)
{
window.open(imageData);
});
Even though i'm using image.onload() with a callback, i'm unable to show the result after the toDataURL() has been processed.
What am i doing wrong?
UPDATE: I tried both the solutions below and they didn't work. I'm using AngularJS and Electron in this project. Any way i can force the code to be synchronous? Or maybe some solution using Promises?
UPDATE #2: #Kaiido pointed out that toDataURL() is in fact synchronous and this issue is more likely due to maximum URI length. Since i'm using Electron and the image preview was for testing purposes only, i'm going to save the file in a folder and analise it from there.
Your code seems absolutely fine. Not sure why isn't working you. Maybe, there are some issues with your browser. Perhaps try using a different one. Also you could use a custom event, which gets triggered when the image conversion is competed.
// using jQuery for custom event
function convertToBase64(url) {
var image = new Image();
image.src = url;
image.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
var imageData = canvas.toDataURL();
$(document).trigger('conversionCompleted', imageData);
};
};
convertToBase64('4mb.jpg');
$(document).on('conversionCompleted', function(e, d) {
window.open(d);
});
This approach might work for you. It shows the image onscreen using the native html element, then draws it to a canvas, then converts the canvas to Base64, then clears the canvas and draws the converted image onto the canvas. You can then scroll between the top image (original) and the bottom image (converted). I tried it on large images and it takes a second or two for the second image to draw but it seems to work...
Html is here:
<img id="imageID">
<canvas id="myCanvas" style="width:400;height:400;">
</canvas>
Script is here:
var ctx;
function convertToBase64(url, callback)
{
var image = document.getElementById("imageID");
image.onload = function() {
var canvas = document.getElementById("myCanvas");
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
ctx = canvas.getContext("2d");
ctx.drawImage(image,0,0);
var imageData = canvas.toDataURL('image/png');
ctx.fillStyle ="#FFFFFF";
ctx.fillRect(0,0,canvas.width,canvas.height);
callback(imageData);
};
image.src = url;
};
var imagename = 'images/bigfiletest.jpg';
window.onload = function () {
convertToBase64(imagename, function(imageData) {
var myImage = new Image();
myImage.src = imageData;
ctx.drawImage(myImage,0,0);
});
}
Note that I also tried it without the callback and it worked fine as well...
I am working on an image generator using HTML5 canvas and jQuery/JS. What I want to accomplish is the following.
The user can upload 2 or max 3 images (type should be png or jpg) to the canvas. The generated images should always be 1080x1920. If the hart uploads only 2 images, the images are 1080x960. If 3 images are uploaded, the size of each image should be 1080x640.
After they upload 2 or 3 images, the user can click on the download button to get the merged image, with a format of 1080x1920px.
It should make use of html canvas to get this done.
I came up with this:
HTML:
<canvas id="canvas">
Sorry, canvas not supported
</canvas><!-- /canvas.offers -->
<input id="fileInput" type="file" />
Generate
jQuery:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.height = 400;
canvas.width = 800;
var img1 = loadImage('http://www.shsu.edu/dotAsset/0e829093-971c-4037-9c1b-864a7be1dbe8.png', main);
var img2 = loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Ikea_logo.svg/266px-Ikea_logo.svg.png', main);
var minImages = 2;
var imagesLoaded = 0;
function main() {
imagesLoaded += 1;
if(imagesLoaded >= minImages) {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.drawImage(img1, 0, 0);
// ctx.translate(canvas.height/2,canvas.width/2); // move to the center of the canvas
// ctx.rotate(270*Math.PI/180); // rotate the canvas to the specified degrees
// ctx.drawImage(img2,0,canvas.height/2);
ctx.translate(-canvas.height/2,canvas.width/2); // move to the center of the canvas
ctx.rotate(90*Math.PI/180); // rotate the canvas to the specified degrees
ctx.drawImage(img2,-img2.width/2,-img2.width/2);
ctx.restore(); // restore the unrotated context
}
}
function loadImage(src, onload) {
var img = new Image();
img.onload = onload;
img.src = src;
console.log(img);
return img;
}
Above code will create the canvas and place both images (that are now hard-coded in JS) to the created canvas. It will rotate 90 degrees, but it will not position to the right corner. Also the second image should be position beside the first one.
How can I do the rotation and positioning of each image side by side?
Working Fiddle: https://jsfiddle.net/8ww1x4eq/2/
Have a look at the updated jsFiddle, is that what you wanted?
Have a look here regarding image rotation
Updated jsFiddle, drawing multiple images.
Notice:
The save script was just a lazy way to make sure I've got the
external scripts loaded before I save the merged_image...
There is no synchornisation in the sample script, notice that addToCanvas
was called on image loaded event, there could be a race condition
here (but I doubt it, since the image is loaded to memory on
client-side)
function addToCanvas(img) {
// resize canvas to fit the image
// height should be the max width of the images added, since we rotate -90 degree
// width is just a sum of all images' height
canvas.height = max(lastHeight, img.width);
canvas.width = lastWidth + img.height;
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (lastImage) {
ctx.drawImage(lastImage, 0, canvas.height - lastImage.height);
}
ctx.rotate(270 * Math.PI / 180); // rotate the canvas to the specified degrees
ctx.drawImage(img, -canvas.height, lastWidth);
lastImage = new Image();
lastImage.src = canvas.toDataURL();
lastWidth += img.height;
lastHeight = canvas.height;
imagesLoaded += 1;
}
PS: I've added some script to download the merged image, but it would fail. The error message was: "Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported."
I've done a quick Google search and it seemed to be related to Cross-origin resources. I assumed that it wouldn't be an issue with FileReader. I haven't had time to test that so please test it (and please let me know :) It works with FileReader!
You can use toDataURL. But in this way user must do something like Save image as...
var img = canvas.toDataURL("image/png");
And then set for example img result src:
$("#result").attr("src",img);
Canvas is already an Image.
The canvas and img are interchangeable so there is no need to add the risky step of canvas.toDataURL which can fail depending on the image source domain. Just treat the canvas as if it were and img and put it in the DOM. Converting to a jpg does not save space (actually a resource hungry operation) as the an img needs to be decoded before it can be displayed.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.height = 400;
canvas.width = 800;
document.body.appendChild(canvas); // add to the end of the document
// or add it to a containing element
var container = document.getElementById("containerID"); // or use JQuery
if(container !== null){
container.appendChild(canvas);
}
I am making a chrome extension that uses the chrome.tabs.captureVisibleTab method to grab a screencap of the current tab and then displays that in a popup from the chrome extension. If I use the img tag and use the data coming from the chrome function, such as data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwME…UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/2Q==, the <img> displays pixel perfect, it is crisp and that's what I want. Problem is that I need to make it into a canvas, and when I do that, it becomes blurry.
This is a screencap of the <img> that uses the link data provided by Google to be used as a comparison to the canvas which is below.
This is the blurry canvas.
This is the code that I am using to try to do this, but I can't figure out how to make the canvas crisp like the image.
chrome.runtime.sendMessage({msg: "capture"}, function(response) {
console.log(response.imgSrc);
var img = document.createElement('img');
var _canvas = document.createElement("canvas");
img.src = response.imgSrc;
img.height = 436;
img.width = 800;
document.getElementById('main-canvas').appendChild(img);
draw(response);
});
function draw(response) {
var canvas = document.getElementById('imageCanvas');
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
//Get a 2d context
var ctx = canvas.getContext('2d');
//use image to paint canvas
var _image = new Image();
_image.onload = function() {
ctx.drawImage(_image, 0, 0, 800, 436);
}
_image.src = response.imgSrc;
document.getElementById('main-canvas').appendChild(canvas);
}
This is what I used to fix my problem: High Resolution Canvas from HTML5Rocks
I am currently using http://paperjs.org to create an HTML5 canvas drawing app. I want to let users upload images into the canvas. I know I need to make a login and signup but is there an easier way? I have seen the HTML5 drag and drop upload.
I assume you mean, to load an image into the canvas and not uploading the image from the canvas.
It'd probably be a good idea to read through all the canvas articles they have over here
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images
But basically what you want to do is create an image in javascript, and set the image.src = to whatever the file location is. In the case of loading images from the user on their end, you're going to want to use the File System API.
Threw together a brief example here: http://jsfiddle.net/influenztial/qy7h5/
function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
One doesn't need a FileReader*, it is better to use the URL.createObjectURL method, which will create a symlink directly to the File on disk. This will incur less memory usage, and will have the added benefit to have only one async event to wait for (the one of the img.onload).
document.getElementById('inp').onchange = function(e) {
var img = new Image();
img.onload = draw;
img.onerror = failed;
img.src = URL.createObjectURL(this.files[0]);
};
function draw() {
var canvas = document.getElementById('canvas');
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0,0);
}
function failed() {
console.error("The provided file couldn't be loaded as an Image media");
}
<input type="file" id="inp">
<canvas id="canvas"></canvas>
*IIRC only a few versions of Chrome did support FileReader while not yet supporting URL.createObejctURL, so if you target these very versions, you might need FileReader..
Modified answer by #kaiido to create a new canvas element each time and append it to a wrapper. Useful when you don't know how many canvases you may need.
Note: There is no new Canvas() constructor, therefore we must use createElement().
document.getElementById('inp').onchange = function(e) {
let img = new Image();
img.onload = draw;
img.onerror = failed;
img.src = URL.createObjectURL(this.files[0]);
};
function draw() {
let canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);
document.getElementById('gallery').append(canvas);
}
function failed() {
console.error("The provided file couldn't be loaded as an Image media");
}
/* entirely decorative */
#gallery {
display: flex;
gap: 1em;
margin: 1em;
}
#gallery canvas {
height: 100px;
border-radius: .5em;
aspect-ratio: 1/1;
object-fit: cover;
}
<input type="file" id="inp">
<div id='gallery'></div>
The most optimal way of creating an image consumable by the canvas is to create an ImageBitmap out of the File you get from the input.
This will use an optimized path to produce just what the browser needs to render that image, and will store the bitmap data in the GPU, allowing for fast drawing when asked to.
Given this is a quite recent feature (Safari added support only last year), you may want to use a polyfill like this one of mine.
document.querySelector("input").oninput = async (evt) => {
try {
const file = evt.target.files[0];
const bitmap = await createImageBitmap(file);
const canvas = document.querySelector("canvas");
canvas.width = bitmap.width;
canvas.height = bitmap.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0);
}
catch(err) {
console.error(err);
}
};
<!-- createImageBitmap polyfill for old browsers --> <script src="https://cdn.jsdelivr.net/gh/Kaiido/createImageBitmap/dist/createImageBitmap.js"></script>
<input type="file">
<canvas></canvas>
<script>
window.onload = function() {
var canvas=document.getElementById(“drawing”); // grabs the canvas element
var context=canvas.getContext(“2d”); // returns the 2d context object
var img=new Image() //creates a variable for a new image
img.src= “images/vft.jpg” // specifies the location of the image
context.drawImage(img,20,20); // draws the image at the specified x and y location
}
</script>
Check Demo