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
Related
PHP creates the text from metadata from image file which stores it in variable of the same name of IMG source.
No Problems
JavaScript displays the gallery to show images, scroll & enlarge.
During enlargement it gives description of image from source attribute but always displays the text with � after every character. But PHP doesn't.
I've tried encoding which you will see from code & & echo header("Content-Type: text/html; charset=ISO-8859-1");
PHP:
$path = "gallery/";
$objs = new RecursiveIteratorIterator(new
RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::SELF_FIRST);
$num = 0;
foreach ($objs as $pic){
$pic = str_replace('gallery/', '', $pic);
if ($pic == '..' or $pic == '.'){
continue;
}
$exif = exif_read_data("$DIR/gallery/$pic", 0, true);
$pic = str_replace('.JPG', '', $pic);
${$pic} = $exif['IFD0']['Comments']; ///// php Variable
echo "<script> var $pic = '".$exif['IFD0']['Comments']."';
var $pic = utf8_encode($pic);</script>";
// JS of variable of same name.
}
Sloppy but Works
JQuery:
$('#mSide').on('click',function(){
var src = $('#mPic').attr('src');
var v = src.replace('/gallery/','');
v = v.replace('.JPG','');
v = unescape(encodeURIComponent(v));
$('#fullPic').show();
$('#fullPic').append('<img class=\"fPic\" src=\"'+src+'\"
height=\"90%\" widdth=\"90%\" style=\"margin-left:0px;\" />');
$('#fullPic').append('<span id=\"picSummary\"
style=\"color:#FFFFFF;\" >testing <textarea > '+ window[v] +'</textarea>
</span>');
$('#fullPic').prepend('<input class=\"closeFullP headr\"
value=\"Close\" READONLY><br class=\"closeFullP\">');
});
Sloppy but Works and window[v] is the call
Should display: this is the new val = NOTICE: This e-mail message may contain legally privileged and/or confidential information. If you are not the intended recipient, you are hereby notified that any dissemination of the contents of this message is strictly prohibited. If you have received this message in error, please immediately notify the sender at ########### and delete all copies of this e-mail message and its attachments.
Not: N�O�T�I�C�E�:� �T�h�i�s� �e�-�m�a�i�l�
�m�e�s�s�a�g�e� �m�a�y� �c�o�n�t�a�i�n�
�l�e�g�a�l�l�y� �p�r�i�v�i�l�e�g�e�d� �a�n�d�/�o�r�
�c�o�n�f�i�d�e�n�t�i�a�l� �i�n�f�o�r�m�a�t�i�o�n�.�
�I�f� �y�o�u� �a�r�e� �n�o�t� �t�h�e�
�i�n�t�e�n�d�e�d� �r�e�c�i�p�i�e�n�t�,...............
Never use utf8_encode() or utf8_decode() they make awful assumptions and happily/silently corrupt your data. Always use a function that allows you to explicitly specify your input and output encodings.
The data you're extracting from EXIF is encoded as UTF16-LE, and your page is... something else. I can't tell what and you should probably figure that out and be consistent.
Suggested reading: UTF-8 all the way through
If your page is encoded as ISO-8859-1:
$proper = mb_convert_encoding($input, 'ISO-8859-1', 'UTF-16-LE');
If your page is encoded as UTF-8:
$proper = mb_convert_encoding($input, 'UTF-8', 'UTF-16-LE');
Ref: https://secure.php.net/manual/en/function.mb-convert-encoding.php
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 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!');
});
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.
How can I upload a image immediately after user pick a file from browser?
Like in Facebook, when you need to upload your cover or profile image, you need to
select file and after that upload starts.
I have for now just my input tag
<input id="chaf" type="file"/>
and js that can run the function after file is picked
$('#chaf').change(function(){
// Upload image start
});
But how can I send the data to php in this way?
You can upload files as a Base64 string using Ajax (without being refreshed).
some thing like this.
$(document).on("change", ".custom-file-input", this, function(e){
GetBase64( e.target );
});
function GetBase64( input ) {
if ( input.files && input.files[0] ) {
var FR= new FileReader();
FR.onload = function(e) {
var str = e.target.result;
/* preview it ( if you wanted to ) */
$('#preview-img').attr( "src", str );
/* upload it to server */
UploadFile( str );
};
FR.readAsDataURL( input.files[0] );
}
}
function UploadFile( file_str ) {
console.log( file_str );
/* use $.ajax to upload your file */
}
refer this answer for storing base64 in disk base64 string to an image file
in php some thing like this
<?php
$base64Str = $_REQUEST[ "your-post-variable" ];
$img = explode(',', $base64Str);
$fp = fopen( "my-image.png" , "wb");
fwrite($fp, base64_decode( $img[1]) );
fclose($fp);
?>
You should check out: https://github.com/Widen/fine-uploader.
This does exactly what you want. It will start uploading the second they select the image.
It allso supports drag& drop and multiple file upload.
Another option - using IaaS for file uploading, such as Uploadcare (this system is maintained by us):
https://uploadcare.com
All you have to do is add the JS library into your header:
<script>
UPLOADCARE_PUBLIC_KEY = 'PUBLIC-KEY';
UPLOADCARE_AUTOSTORE = true;
</script>
<script charset="utf-8" src="https://ucarecdn.com/widget/1.4.6/uploadcare/uploadcare-1.4.6.min.js"></script>
and replace file input with specially marked hidden input in your form:
<input type="hidden" role="uploadcare-uploader" name="file_fieldname" />
It will add a widget to the page. Once the file is selected (from local drive, URL, Dropbox/Box/GoogleDrive/Facebook/Instagram/etc.) or dropped onto the widget, upload will start immediately.
The form will send an UUID of the uploaded file to your server, so you can store a reference to it.