Resize images with canvas before uploading - javascript

I have recently written a script to upload images. Everything works well. But now I want to resize the image after uploading it. I have done some research on it and I want to try it with the <canvas> element. I have parts of the script, others are missing and I don't know how to connect everything.
These are the steps:
Upload the image into img/uploads - Done.
<form action="picupload.php" method="post" enctype="multipart/form-data">
<input name="uploadfile" type="file" accept="image/jpeg, image/png">
<input type="submit" name="btn[upload]">
</form>
picupload.php:
$tmp_name = $_FILES['uploadfile']['tmp_name'];
$uploaded = is_uploaded_file($tmp_name);
$upload_dir = "img/uploads";
$savename = "[several code]";
if($uploaded == 1)
{
move_uploaded_file (
$_FILES['uploadfile']['tmp_name'] ,
"$upload_dir/$savename");
}
Put the image into a canvas element - Missing
Resize it - Part of the code I want to use somehow:
var MAX_WIDTH = 400;
var MAX_HEIGHT = 300;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
Replace the existing image with the new resized one. - Missing
It would be very nice if someone would give me some tips to complete it - Thank you!

(#2-3) Resizing the source image onto a canvas
Calculate the scaling factor required to fit MAX dimensions without overflow
Create a new canvas with the scaled dimensions
Scale the original image and draw it onto the canvas
Important! Be sure the source image is coming from the same domain as your web page or else toDataURL will fail for security reasons.
(#4) You can convert the canvas from #3 to an image with resizedImg.src=context.toDataURL
Example annotated code and a Demo:
var MAX_WIDTH = 400;
var MAX_HEIGHT = 300;
var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/annotateMe.jpg";
function start(){
var canvas=fitImageOntoCanvas(img,MAX_WIDTH,MAX_HEIGHT);
// #4
// convert the canvas to an img
var imgResized=new Image();
imgResized.onload=function(){
// Use the new imgResized as you desire
// For this demo, just add resized img to page
document.body.appendChild(imgResized);
}
imgResized.src=canvas.toDataURL();
}
// #3
function fitImageOntoCanvas(img,MAX_WIDTH,MAX_HEIGHT){
// calculate the scaling factor to resize new image to
// fit MAX dimensions without overflow
var scalingFactor=Math.min((MAX_WIDTH/img.width),(MAX_HEIGHT/img.height))
// calc the resized img dimensions
var iw=img.width*scalingFactor;
var ih=img.height*scalingFactor;
// create a new canvas
var c=document.createElement('canvas');
var ctx=c.getContext('2d');
// resize the canvas to the new dimensions
c.width=iw;
c.height=ih;
// scale & draw the image onto the canvas
ctx.drawImage(img,0,0,iw,ih);
// return the new canvas with the resized image
return(c);
}
body{ background-color:white; }
img{border:1px solid red;}

I would recommend using ajax for upload, since when you upload you redirect to the php page.
But the example I didn't use it either
References:
http://stackoverflow.com/questions/12368910/html-display-image-after-selecting-filename
http://stackoverflow.com/questions/4459379/preview-an-image-before-it-is-uploaded
http://stackoverflow.com/questions/6011378/how-to-add-image-to-canvas
http://stackoverflow.com/questions/331052/how-to-resize-html-canvas-element
http://stackoverflow.com/questions/2142535/how-to-clear-the-canvas-for-redrawing
Here is what I have for html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
</style>
<title>Something</title>
</head>
<body>
<form action="picupload.php" method="post" enctype="multipart/form-data">
<input name="uploadfile" type="file" accept="image/jpeg, image/png">
<input type="submit">
</form>
</body>
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
<script>
</script>
</html>
For PHP I used a different way for file upload (for instance I store the picture in localhost/):
<?php
if(isset($_FILES['uploadfile']['name'])){
$nameFile=$_FILES['uploadfile']['name'];
$pathFile = "C:/inetpub/wwwroot/" . $_FILES['uploadfile']['name'];
$file_tmp2=$_FILES['uploadfile']['tmp_name'];
move_uploaded_file($file_tmp2, $pathFile);
}
echo ("
<!DOCTYPE html>
<html>
<head>
<meta name='viewport' content='initial-scale=1.0, user-scalable=no'>
<meta charset='utf-8'>
<style>
</style>
<title>Something</title>
</head>
<body>
<canvas id='viewport' ></canvas>
<button onclick='change()'>change</button>
</body>
<script>
var canvas = document.getElementById('viewport'),
context = canvas.getContext('2d');
make_base();
function make_base()
{
base_image = new Image();
base_image.src = '").$_FILES['uploadfile']['name'];
echo("';
base_image.onload = function(){
context.drawImage(base_image, 100, 100);
}
}
function change(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(base_image, 0, 0, 400 ,300);
}
</script>")
?>

Related

canvas.fillRect not displaying rectangle on browser window [duplicate]

This question already has answers here:
Size of HTML5 Canvas via CSS versus element attributes
(3 answers)
Closed 2 years ago.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Archade!</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div style="text-align: center;">
<canvas id="gameCanvas"></canvas>
</div>
<script>
var canvas;
var canvasContext;
window.onload = function () {
console.log("Game working!");
canvas = document.getElementById("gameCanvas");
canvasContext = canvas.getContext("2d");
canvasContext.fillStyle = "black";
canvasContext.fillRect(0, 0, canvas.width, canvas.height);
console.log("Loading red box");
canvasContext.fillStyle = "red";
canvasContext.fillRect(500, 500, 50, 25);
console.log("Red box should be loaded!");
};
</script>
</body>
</html>
This is my html code, [ in style.css i've just set width and height of the canvas ].
The black canvas is being displayed on the screen but the red box isn't displayed anywhere.
The console log above and below the red rectangle is also working fine.
Please help me fix this! I want the red rectangle to be displayed as well.
Thanks for your time :)
From this reference - https://www.w3schools.com/tags/canvas_fill.asp
You can do the following:
First draw the rectangle.
Then, set the fillStyle.
Then fill the rectangle.
Check the code below:
var canvas;
var canvasContext;
window.onload = function() {
console.log("Game working!");
canvas = document.getElementById("gameCanvas");
canvasContext = canvas.getContext("2d");
canvasContext.rect(0, 0, canvas.width, canvas.height);
canvasContext.fillStyle = "black";
canvasContext.fill();
console.log("Loading red box");
canvasContext.rect(500, 500, 50, 25);
canvasContext.fillStyle = "red";
canvasContext.fill();
console.log("Red box should be loaded!");
};
<div style="text-align: center;">
<canvas id="gameCanvas"></canvas>
</div>
Setting the canvas size in css might not be enough.
Try also setting the width/height attributes of the canvas element.
For example:
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
I think the red rectangle isn't displayed because it's position exceeds the default size of a canvas.

Display pdf with transparent background with pdf.js

I have a pdf with 4 pages, each of the page has a transparent background. I use pdf.js to display them, but I would like to display them with a transparent background on my html page but I can't figure out how I could do that, there is always a white background :
I think it is possible according to this issue, but when I change the line page.render(renderContext); to page.render({renderContext, viewport, backgroundColor: 'rgba(0,0,0,0)' }); (as it said in the issue) I have the following error :
Any idea on how I could manage that ?
I use pdf.js version v1.9.426 and Firefox 55.0.2 (64 bits).
EDIT :
With the following code I have no error in the console but the background of my pdf file is still white. (However, If open the pdf with for example photoshop there is no background)
Link to the PDF file I use : tempPDF.pdf
Here is my javascript file to display the four pages :
var pdfFile;
PDFJS.getDocument('/assets/pdf/tempPDF.pdf').then(function (pdf) {
pdfFile = pdf;
for(var i = 1; i <= 5; i++) {
var canvas = document.getElementById('canvas'+i);
var context = canvas.getContext('2d');
PDFJS.disableStream = true;
openPage(pdf, i, context, 50);
}
});
function openPage(pdfFile, pageNumber, context, ratio) {
var scale = 10;
pdfFile.getPage(pageNumber).then(function (page) {
viewport = page.getViewport(scale);
// reference canvas via context
var canvas = context.canvas;
canvas.width = viewport.width;
canvas.height = viewport.height;
canvas.style.width = ratio+"%";
canvas.style.height = ratio+"%";
var renderContext = {
canvasContext: context
, viewport: viewport
};
page.render({canvasContext: context, viewport: viewport, backgroundColor: 'rgba(0,0,0,0)' });
//page.render(renderContext);
});
}
And my html page in case that could be useful :
<!DOCTYPE html>
<html>
<body
style="background-color:powderblue;">
</body>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta name="description" content="PDF Viewer" />
<title>My page</title>
</head>
<body>
<form action="pdf_latex_test.php">
<input type="submit" value="execute" /> </form>
</body>
<body>
<canvas id="canvas1" width="300" height="300"></canvas>
<canvas id="canvas2" width="300" height="300"></canvas>
<canvas id="canvas3" width="300" height="300"></canvas>
<canvas id="canvas4" width="300" height="300"></canvas>
<script src="/assets/js/pdf.js"></script>
<script src="/assets/js/pdf.worker.js"></script>
<script src="/assets/js/pdf.latex.main.js"></script>
</body>
</html>
The change and API documentation shows that property name must be background:
var url = '//cdn.mozilla.net/pdfjs/helloworld.pdf';
PDFJS.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';
var loadingTask = PDFJS.getDocument(url);
loadingTask.promise.then(function(pdf) {
var pageNumber = 1;
pdf.getPage(pageNumber).then(function(page) {
console.log('Page loaded');
var scale = 1.5;
var viewport = page.getViewport(scale);
// Prepare canvas using PDF page dimensions
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: context,
// Use transparent background!
background: 'rgba(0,0,0,0)',
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.then(function () {
console.log('Page rendered');
});
});
}, function (reason) {
// PDF loading error
console.error(reason);
});
#the-canvas {
border:1px solid black;
background-image: url(http://image.blingee.com/images19/content/output/000/000/000/7c8/805674825_1628628.gif?6);
}
<script src="//mozilla.github.io/pdf.js/build/pdf.js"></script>
<canvas id="the-canvas"></canvas>

Empty images when resizing images using canvas

I'm developing an image resizer for files from input field with multiple files.
The files are first added to an array of Json objects, because i use that array in my webapp to add, remove and rearrange objects.
My problem is that Firefox and IE11 both presents empty images when traversing trough the filelist, and I can't figure out what is going wrong, and i neither has figured out a workaround for Firefox and IE. Chrome resizes and show the images ok.
I have tried two diferent methods. A serial function traversing trough the files array, and a asyncronous read-resize-show function. Both have the same problem with empty images.
The HTML is:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
<script src="test.js"></script>
</head>
<body>
<input type="file" name="file" id="file" onChange="showFile(this)" multiple>
<input type="button" value="Show one by one" onClick="showPicturesSerial(dataArray,0)">
<input type="button" value="Show asyncronous" onClick="showPicturesAsync(dataArray)">
<div id="imageListSer" style="width:auto;min-height:150px;border:1px solid black;"></div>
<div id="imageListAsn" style="width:auto;min-height:150px;border:1px solid black;"></div>
</body>
</html>
The JavaScript is:
dataArray=new Array();
showFile=function(obj){
for(i=0;i<obj.files.length;i++){
dataArray[i]={
file:obj.files[i],
data:{
name:obj.files[i].name,
size:obj.files[i].size,
type:obj.files[i].type
// Add more values
}
}
}
}
showPicturesSerial=function(files,i){
var imageListSer=document.querySelector("#imageListSer");
if(i==0)imageListSer.innerHTML="";
isPic=/^image\//
if(i<files.length&&isPic.test(files[i].file.type)){
var file=files[i].file;
var reader=new FileReader();
reader.onerror=function(error) {
console.log ("error",error);
i++;
setTimeout(showPicture(files,i),999999);
}
reader.onload=function(e) {
var canvas=document.createElement("canvas");
var tImg=document.createElement("img");
var src;
src=e.target.result;
tImg.src=src;
var MAX_WIDTH=150;
var MAX_HEIGHT=150;
var width=tImg.width;
var height=tImg.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width=MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height=MAX_HEIGHT;
}
}
canvas.width=width;
canvas.height=height;
var ctx=canvas.getContext("2d");
ctx.drawImage(tImg, 0, 0, width, height);
var img=document.createElement("img");
img.src=canvas.toDataURL();
var div=document.createElement("div");
div.style.display="inline-block";
div.appendChild(img)
div.appendChild(document.createElement("br"));
div.appendChild(document.createTextNode(file.name));
div.appendChild(document.createElement("br"));
div.appendChild(document.createTextNode(file.type));
imageListSer.appendChild(div);
console.log("finished:",file.name);
i++;
return showPicturesSerial(files,i);
}
reader.readAsDataURL(file);
}
}
function showPicturesAsync(files) {
var imageListAsn=document.querySelector("#imageListAsn")
for (var i=0; i < files.length; i++) {
if(i==0)imageListAsn.innerHTML="";
isPic=/^image\//
if(!isPic.test(files[i].file.type))return;
var file=files[i].file;
if (!/^image\//.test(file.type)) {continue;}
var canvas=document.createElement("canvas");
var img=document.createElement("img");
var div=document.createElement("div");
div.style.display="inline-block";
div.appendChild(img);
div.appendChild(document.createElement("br"));
div.appendChild(document.createTextNode(file.name));
div.appendChild(document.createElement("br"));
div.appendChild(document.createTextNode(file.type));
imageListAsn.appendChild(div);
var reader=new FileReader();
reader.onerror=function(error) {
console.log ("error",error);
}
reader.onload=(function(aImg) { return function(e) {
var bImg=document.createElement("img");
var canvas=document.createElement("canvas");
bImg.src=e.target.result;
var MAX_WIDTH=150;
var MAX_HEIGHT=150;
var width=bImg.width;
var height=bImg.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width=MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height=MAX_HEIGHT;
}
}
canvas.width=width;
canvas.height=height;
var ctx=canvas.getContext("2d");
ctx.drawImage(bImg, 0, 0, width, height);
aImg.src=canvas.toDataURL();
console.log("finished:",i);
};
})(img);
reader.readAsDataURL(file);
}
}
I hope someone can figure out this problem.

Image width in canvas isnt being displayed correctly

I have this canvas I'm drawing onto. And I want to make image to be placed in the left lower corner.
var canvasWidth = 800;
var canvasHeight = 600;
$("#gameCanvas").attr("width", canvasWidth);
$("#gameCanvas").attr("height", canvasHeight);
var canvas = $("#gameCanvas")[0].getContext("2d");
var image = new Image();
image.src="you.png";
var player1X =0;
var imageHeight=image.height;
var player1Y = canvasHeight - imageHeight;
canvas.rect(0, 0, canvasWidth, canvasHeight);
canvas.fillStyle="#5c7792";
canvas.fill();
$(image).load(function(){
canvas.drawImage(image, player1X , player1Y);
});
but the problem is that when I use variable player1Y, it results in image being displayed at coordinates (0, canvasHeight). Actually, it results in image not being shown. But when I write canvas.drawImage(image, player1X, canvasHeight - image.height) it works perfectly.
How do I make the variable to control the posiotion of image?
Here is JSfiddle: http://jsfiddle.net/u9Ehs/10/
The problem is that the image hasn't fully loaded when you are setting imageHeight & player1Y.
Refactor your code to set all image related variables inside image.onload:
Example code and a Demo: http://jsfiddle.net/m1erickson/CSQGh/
<!doctype html>
<html>
<head>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
window.onload = function() {
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var player1X=0;
var player1Y;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/ship.png";
function start(){
player1Y=canvas.height-img.height;
ctx.drawImage(img,player1X,player1Y);
}
}; // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Why does canvas context drawImage fail on iPhone

The objective is to have the users choice of photograph displayed on both the image and canvas elements.
Why does this code work on Firefox, Chrome, IE, iPad but not on iPhone? On iPhone 3GS or iPhone 5 the canvas (red border) is simply shown blank albeit the correct size.
It does seem to work for iPhone screen captures but not photographs. Web Inspector gives us nothing.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/>
<title></title>
<style type="text/css">
html, body{font-size:120%;}
#diag{ font-family:'Courier New';}
img{border:2px solid blue;}
canvas{border:2px solid red;}
</style>
<script type="text/javascript">
var reader = new FileReader();
var prev;
function go() {
prev = new Date();
diag('');
diag('start');
var imgFile = document.getElementById('submitfile');
if (imgFile.files && imgFile.files[0]) {
reader.onloadend = function () {
diag('reader.onloadend');
diag('reader.result.length=' + (reader.result.length / 1024.0 / 1024.0).toFixed(4) + "mb");
var img = new Image();
img.onload = function () {
diag('img.onload');
var cvs = document.createElement("canvas");
var ctx = cvs.getContext("2d");
diag("img.width:" + this.width);
diag("img.height:" + this.height);
cvs.width = this.width;
cvs.height = this.height;
diag("cvs.width:" + cvs.width);
diag("cvs.height:" + cvs.height);
ctx.drawImage(this, 0, 0);
ctx.font = '18pt Calibri';
ctx.fillStyle = 'red';
ctx.fillText('CANVAS COPY', 100, 100);
document.body.appendChild(cvs); // new canvas
document.body.appendChild(this); // img element
diag('ctx.drawImage');
};
img.src = reader.result;
}
}
reader.readAsDataURL(imgFile.files[0]);
diag('reader.readAsDataURL');
}
function diag(msg) {
var now = new Date();
var ms = now.getTime() - prev.getTime();
var current_diag_text = document.getElementById("diag").innerHTML;
var new_diag_text = ms + "ms " + msg + "<br/>" + current_diag_text;
if (msg === '') {
document.getElementById("diag").innerHTML = '';
} else {
document.getElementById("diag").innerHTML = new_diag_text;
}
prev = now;
}
</script>
</head>
<body>
<form name="Upload" action="#" enctype="multipart/form-data" method="post">
<p id="diag"></p>
<p>Choose Photo: <input type="file" name="submitfile" id = "submitfile" />
<input type="button" value="Send" onclick="go();" /></p>
</form>
</body>
</html>
We've now learnt of two issues here, one is a memory limitation of mobile safari described at https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW15. This can be overcome by adding portions of the image to canvas rather than all in one go. The next limitation is a problem with mobile safari scaling the resulting canvas image incorrectly.
Both of these issues are avoided by using the excellent mega pixel image rendering library # https://github.com/stomita/ios-imagefile-megapixel.
As to my knowledge above given Script is not even working on IPad

Categories

Resources