I found a great image cropper tool to use for my application.
http://tympanus.net/codrops/2014/10/30/resizing-cropping-images-canvas/
Works perfect, crops just like I want, but I can't figure out how to save the cropped file via PHP/AJAX. While there are many files involved, the 3 to modify are:
index.php (Cropper Tool)
savefile.php
js/component.js (the main functions)
In the comments of the above linked article, someone altered the JS to send an AJAX call to a PHP file to 'save' the cropped image. I can't get it to work.
Here's the code and my modifications to component.js
crop = function(){
//Find the part of the image that is inside the crop box
var crop_canvas,
left = $('.overlay').offset().left - $container.offset().left,
top = $('.overlay').offset().top - $container.offset().top,
width = $('.overlay').width(),
height = $('.overlay').height();
crop_canvas = document.createElement('canvas');
crop_canvas.width = width;
crop_canvas.height = height;
crop_canvas.getContext('2d').drawImage(image_target, left, top, width, height, 0, 0, width, height);
//=== set our canvas data
var canvasData = crop_canvas.toDataURL('image/png');
//=== call ajax to fire php save function
var ajax = new XMLHttpRequest();
ajax.open('POST','savefile.php',true);
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(canvasData);
//=== displays image in new window to prove its working
window.open(crop_canvas.toDataURL('image/png'));
}
The next part is the savefile.php. I can never tell if this is actually firing or not since nothing is saved.
<?php
$imageData = $_POST['data'];
//==== replace with dynamic names later ===
$imgFile = “test.jpg”;
if (!empty($imageData)) {
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, “,”)+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
// Save file.
$fp = fopen( '$imgFile', ‘wb’ );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
header (‘Location: index.php’);
?>
Insight is greatly appreciated - spent all Friday night trying to debug to no avail!
You may require only few changes, still I am posting both ajax and php codes.
Here, I am not looking towards the canvas and dataURL, and I consider canvasData as dataURL.
Here is ajax, first select xmlhttp method as per browser, open ajax query, add request header, and send data.
if (window.XMLHttpRequest)
{ xmlhttp = new XMLHttpRequest();
} else {xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
functions(xmlhttp.responseText);} }
xmlhttp.open("POST","test1.php",true);
xmlhttp.setRequestHeader('Content-Type', 'application/upload');
xmlhttp.send(canvasData);
In php, the post of data will be coming as "HTTP_RAW_POST_DATA". So the PHP will be as follows.
if(isset($GLOBALS["HTTP_RAW_POST_DATA"])) //if data send
{
$imgFile = 'test.jpg'; //set file name to write
$imageData=$GLOBALS['HTTP_RAW_POST_DATA']; //copy data from globals to variable
$filteredData=substr($imageData, strpos($imageData, ",")+1); //filter dataurl string
$unencodedData=base64_decode($filteredData); //decode url
$fp = fopen( $imgFile, 'wb' ); //open file with write permission
fwrite( $fp, $unencodedData); //write file
fclose( $fp ); //close the filehandling
}
Your $imageData variable gets empty $_POST['data'] (I guess). Try using FormData:
var ajax = new XMLHttpRequest();
ajax.open('POST','savefile.php',true);
var data = new FormData();
data.append('data', canvasData);
ajax.send(data);
or as You are already using jQuery:
$.post('saveimage.php', {data: canvasData}, function(){
alert('Image saved!');
});
Related
I have a Server Send Event working and updating a webpage. I then assign the contents of the div receiving the SSE to a var so as to send it to a php file to insert into a database. The div's data is constantly changing in sseReceiving.php page, but how to send it and it's changing values to the database dynamically. Now it is only sending the div content to the database when the page is re-submitted. How to do it continually?
sseTriggering.php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
//generate random number for demonstration
$new_data = rand(0, 1000);
//echo the new number
//echo "data: New random number:". $new_data. "\n\n";
echo "data:".$new_data."\n\n";;
flush();
sseReceiving.php
<body>
<div id="serverData">Here is where the server sent data will appear</div>
<script type="text/javascript">
//check for browser support
if(typeof(EventSource)!=="undefined") {
//create an object, passing it the name and location of the server side script
var eSource = new EventSource("sseTriggering.php");
//detect message receipt
eSource.onmessage = function(event) {
//write the received data to the page
document.getElementById("serverData").innerHTML = event.data;
var MyDiv = document.getElementById("serverData").innerHTML;
window.location.href = "findpair.php?pair=" + MyDiv;
};
}
</script>
</body>
findpair.php
$pair = $_GET['pair'];
$qX = "UPDATE product SET prod_name = '$pair' WHERE id = 1";
$rrr = mysqli_query ($dbc, $qX) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
I have researched this issue at the links below and some have helped me get it to the stage it is at now.
http://www.coderslexicon.com/the-basics-of-passing-values-from-javascript-to-php-and-back/
send javaScript variable to php variable
Get content of a DIV using JavaScript
Detect element content changes with jQuery
I have also put header('Refresh: 5'); in the php part of the various files and no change.
You should be able to send the request via AJAX for your main function which will allow the sse events to come to your client and then go to your findpair.php function.
if(typeof(EventSource)!=="undefined") {
//create an object, passing it the name and location of the server side script
var eSource = new EventSource("sseTriggering.php");
//detect message receipt
eSource.onmessage = function(event) {
//write the received data to the page
document.getElementById("serverData").innerHTML = event.data;
//Send AJAX request.
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
if (xmlhttp.status == 200) {
//Do something with 'xmlhttp.responseText' if you want.
}
else if (xmlhttp.status == 400) {
alert('There was an error 400');
} else {
alert('something else other than 200 was returned');
}
}
};
xmlhttp.open("GET", "findpair.php?pair=" + event.data, true);
xmlhttp.send();
};
}
More info here on submitting AJAX requests with javascript.
I am trying to upload an image created from Java's toDataURL, submitted in a form automatically with javascript, captured by PHP and converted using imagecreatefrompng() and assigned to a variable.
Here is the code to start with:
Javascript code:
if(getImageData == true){
console.log("Saving avatar as image...");
window.setTimeout(function () {
imgData = renderer.domElement.toDataURL("image/png");
document.getElementById('avatarimg').src = imgData;
document.getElementById("timg").value = imgData;
console.log(imgData);
document.getElementById("form1").submit();
console.log("Avatar saved as PNG img.");
}, 300);
getImageData = false;
PHP code:
if($_POST['timg']){
$renderedav = imagecreatefrompng($_POST['timg']);
imageAlphaBlending($renderedav, true);
imageSaveAlpha($renderedav, true);
$target = "images/Avatars/";
$newname = md5($_POST['timg']);
echo ("<font color='#000000'>Image rendered. - " . $newname . " </font>");
$target = $target . $newname . ".png";
if(move_uploaded_file($renderedav, $target))
{ echo("File uploaded."); }else{echo("Error uploading file.");}
}
When I display the image as a raw img using the imgData, everything looks great, but I want to create an actual image from that data and upload it to a directory on my database using the name created in $newname. Is this possible to do? Am I going about it correctly? I know move_uploaded_file() is intended to move a suspended file from a file form element to a new location, but in my research I couldn't find another method that does this.
There are a couple things here that are not going to work:
You can not write text over top by echoing some html, you have to use a gdlib text function like imagettftext(). One note, you have to point to a font file to use it (Resource here). If you are not trying to write this echo ("<font color='#000000'>Image rendered. - " . $newname . " </font>"); over top of the image, disregard this part of the script HOWEVER, you still can not do it because if you echo anything (or have empty space before your script), it will corrupt the image.
You have to use imagepng() (Resource here) to save the file.
PHP Script:
if($_POST['timg']){
// Set file path info
$target = "images/Avatars/";
$newname = md5($_POST['timg']);
$target = $target.$newname.".png";
// Start gdlib functions
$renderedav = imagecreatefrompng($_POST['timg']);
imagealphablending($renderedav, true);
imagesavealpha($renderedav, true);
$fColor_white = imagecolorallocate($renderedav, 255, 255, 255);
// Path to truetype font
$font = 'font.TTF';
// Add text to image
imagettftext($renderedav, 25, 0, 75, 300, $fColor_white, $font, "Image rendered. - ".$newname);
// Here you output the png and use the second parameter to save to a destination
imagepng($renderedav,$target);
// Now you destroy the resouce
imagedestroy($renderedav);
}
I followed this tutorial on my vps: http://permadi.com/2010/10/html5-saving-canvas-image-data-using-php-and-ajax/
testSave.php
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
//echo "unencodedData".$unencodedData;
$randnum = rand(1111111111,9999999999);
// Save file. This example uses a hard coded filename for testing,
// but a real application can specify filename in POST variable
$tmpfname = tempnam("http://123.xx.xx.xx/test/tmp/", "FOO");
$fp = fopen(http://123.xx.xx.xx/test/test . uniqid() .".png","wb");
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
JS
function saveViaAJAX()
{
var testCanvas = document.getElementById("testCanvas");
var canvasData = testCanvas.toDataURL("image/png");
var postData = "canvasData="+canvasData;
var debugConsole= document.getElementById("debugConsole");
debugConsole.value=canvasData;
//alert("canvasData ="+canvasData );
var ajax = new XMLHttpRequest();
ajax.open("POST",'testSave.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
//ajax.setRequestHeader('Content-TypeLength', postData.length);
ajax.onreadystatechange=function()
{
if (ajax.readyState == 4)
{
//alert(ajax.responseText);
// Write out the filename.
document.getElementById("debugFilenameConsole").innerHTML="Saved as<br><a target='_blank' href='"+ajax.responseText+"'>"+ajax.responseText+"</a><br>Reload this page to generate new image or click the filename to open the image file.";
}
}
ajax.send(postData);
}
The problem is that when the user clicks 'send via ajax', there is no image sent/generated in the server directory(http://prntscr.com/8bhmxa). This is the outcome: http://prntscr.com/8bhi62 and everything in the directory remains unchanged.
What should happen is for a link of the image to be generated under the 'Saved as'
Any solutions?
P.S.
Is there anyway to echo the image link with php?
The problem is with your AJAX. Refer Url here the code is given for saving canvas with php and ajax.
Link
Situation:
I am reading the content of a .txt file with php and with AJAX i load the content into a div. The javascript checks every 5 seconds the .txt file and put the content into the div.
If the content of the .txt file changes, (which i do with a form submit), the content of the div changes automatically after 5 seconds.
For this; i use a checkbox with 3 options:
Status: Available
Status: Busy
Status: Paused
One of the 3 lines above is in the .txt file.
Situation now: every 5 seconds check of the .txt file and every 5 seconds refresh of the div. Is it possible that if the content of the .txt file has not changed, to keep the refresh away?
How can i achieve this?
Below the javascript:
function Ajax()
{
var
$http,
$self = arguments.callee;
if (window.XMLHttpRequest) {
$http = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
$http = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
$http = new ActiveXObject('Microsoft.XMLHTTP');
}
}
if ($http) {
$http.onreadystatechange = function()
{
if (/4|^complete$/.test($http.readyState)) {
document.getElementById('ReloadThis').innerHTML = $http.responseText;
setTimeout(function(){$self();}, 5000);
}
};
$http.open('GET', 'loadtxt.php' + '?' + new Date().getTime(), true);
$http.send(null);
}
}
Loadtxt.php
<?php
//
$file = "status.txt";
$f = fopen($file, "r");
while ( $line = fgets($f, 5000) ) {
echo $line;
}
?>
The div:
<script type="text/javascript">
setTimeout(function() {Ajax();}, 5000);
</script>
<div id="ReloadThis">Default text</div>
Calculate the HASH of the file on the server-side have your AJAX check with the for the hash (say a SHA1 or an MD5) - and only update the DIV if the hash has changed since it last looked ?
Maybe this PHP function on the server could help here ?
string hash_file ( string $algo , string $filename [, bool $raw_output = false ] )
Which I found on this link : http://php.net/manual/en/function.hash-file.php
So something like this (I am not in a position to test this; so edits are very welcome here):
filehash.php:
<?php
$file = "status.txt";
echo hash_file( "SHA1", $file, $raw_output=false )
?>
Set up a Javascript variable like 'fileHash':
var fileHash;
populate with an AJAX call to the new PHP script:
[...]
$http.open('GET', 'filehash.php' , true);
newFileHash=$http.responseText;
if (fileHash!=newFileHash) { // file changed - so fetch contents
[...]
// check me here: can we just make use of $http twice here ?
$http.open('GET', 'loadtxt.php' + '?' + new Date().getTime(), true);
// update div.
document.getElementById('ReloadThis').innerHTML =$http.responseText;
fileHash=newFileHash;
}
setTimeout(function(){$self();}, 5000);
[...]
Alternative suggestion:
Your webserver might be able to automatically return a HTTP code to state that the file hasn't changed since it was last requested (by comparing with your browser headers) - with an HTTP 304 for instance:
From Wikipedia:
304 Not Modified
Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or
If-None-Match. This means that there is no need to retransmit the
resource, since the client still has a previously-downloaded copy.
It looks like you have added a timestamp parameter to your GET request - which I presume is prevent your browser caching the old copy of the text file: if you do opt for the method above, you should remove this from your GET request - as this will appear to the webserver that you are asking for a new document each time.
I am developing an application that use HTML and js for front-end and PHP for back-end. I have the following code which should have the functions that: 1, when click on the background image, user can choose photo from there phone as new background image, and use PHP to save the image on server and get the image path, store the path into database, then send new path back to front with JSON, and display the selected image as new background image. Thanks for any help.
javascript for sending and retrieve data:
function UploadImageDialog()
{
$("#newProfileImage").click();
}
function profileImageSelected(fileInput)
{
var xhr = new XMLHttpRequest();
xhr.open("POST", "UploadProfileImage.php", true);
var formData = new FormData();
formData.append("file", fileInput.files[0]);
xhr.send(formData);
xhr.onload = function() {
alert(xhr.responseText); //test the returned info from PHP.
if(xhr.responseText != ""){
$("#profileBackgroundImage").setAttribute("src", xhr.responseText);
}
else
{
alert("Your file failed to upload");
}
}
}
HTML code to call the javascript:
<div style="width:91.5vw;height:78.5vh;margin-top:10.5vh;">
<img class="backgroundImage" id="pictureSrc" src="img/Jenny.jpg" onclick="UploadImageDialog()" />
</div>
<input type="file" id="newProfileImage" style="display:none;" onchange="profileImageSelected(this)"/>
PHP code to get the path:
<?php
if(is_uploaded_file($_FILES['file']['tmp_name'])) // if user uploads file
{
if (!file_exists("./img/EventImages/" . $_FILES["file"]["name"]))
{
if (move_uploaded_file($_FILES["file"]["tmp_name"], "./img/EventImages/" . $_FILES["file"]["name"]))
{
echo "img/EventImages/" . $_FILES["file"]["name"];
}
}
else
{
echo "img/EventImages/" . $_FILES["file"]["name"];
}
}
?>
You should use some libraries like uploadify to upload files without posting form.
DEMO
I have figured that out. There was nothing wrong with the code, but I didn't set the Directory Permission correctly on the server.