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);
}
Related
I have created a QR code generating website. QR code is generated through PHP QR code generator library
by using this code
include_once "../phpqrcode/qrlib.php";
$PNG_TEMP_DIR = '../qrcodeImages/';
if (isset($_REQUEST['text'])) {
$content = $_REQUEST['text'];
$filename = $PNG_TEMP_DIR . 'qr' . md5($content) . '.png';
QRcode::png($content, $filename, 10);
echo $image = "<img class='img' src='qrcodeImages/" . basename($filename) . "'/>";
// $image_src = "qrcodeImage/" . basename($filename);
};
with this ajax call i append the QR code in the required div
$.ajax({
url: "code/single_input_to_qrcode.php",
type: "POST",
data: { text: jquery_plain_text },
success: (parms) => {
$("#downloadPart_img img").remove();
$("#downloadPart_img").append(parms);
}
});
and under QR code div I have placed a download button which is used to download the QR code
for downloading purpose I have used JavaScript library "File Saver"
code
var url = $("#downloadPart_img img").attr('src');
if (url == "img/white-qr-code.png") {
$("#error_msg_div").animate({ "top": "20px" });
error_msg = "Please generate a QR code before download";
error_msg_div.html(error_msg);
} else {
var file_name = url.substring(url.lastIndexOf('/') + 1);
url = "localhost/qrCodeGenerator/" + url;
saveAs(url, file_name);
}
But when user hit download button it show failed to download what kind of issue is that. I thinks this is because when the user hit the download button at the same time the file is saving in the folder so file is not available their at that time.
I have search a lot about that but I am fail to get its solution so now I am on this site to find solution so if some one now how to fix this problem so please help me.
Advance thanks
image of website and failed file at left bottom
I have a form that has been working perfectly fine when it comes to uploading files and large images. For any image that is too large it gets resized using a canvas and then I append it to the form Data and it saves perfectly. However I have now been asked to allow videos and audio files to be uploaded on the same file input.
This sort of has thrown me for a bit of a loop because even shorter videos from a phone can be 50MB or more especially if the quality of the camera is good. I searched for a number of things but I can't seem to find something that already somewhat works with the submission process I have going on.
I saw I can split the file into chunks and upload it in pieces to the server, but the other unfortunate part is when I submit the file (image, pdf, mp4, mp3) I am also submitting other information, like Description (small paragraph describing the file), name of person submitting the file etc.
My current process goes a little something like this:
Person uploads file + information, I send it away using formData and new XMLHttpRequest().
On the server side I get the name, set the path and get a date for the submission. The name of the image/file gets changed to be something like 20200128200812_imageName.jpeg which helps me retrieve the image based on what time the form was submitted (database column frmSubmitted).
What I am attempting to do:
Allow a user submit a form with the ability to process video types and audio types but still process the information that is associated with the file, like name or description.
I'm afraid if I submit the video or audio file in chunks, I will be also submitting the other information as well, I might be wrong on this but all other posts I have read seem to mention making separate requests might be the only way to do this. The following code works and is how I am currently set up but I am including it for context.
html
<input type="text" id="name"/>
<textarea id="description" name="description" rows="5" cols="50" maxlength="2000"></textarea>
<input type="file" name="sFile" id="sFile" multiple />
<button onclick="submitFile();" class="btn" >submit</button>
JS
function submitFile(){
const files= document.querySelector('#sFile').files;
var formData = new FormData();
if (files.length > 0){
for (var i = 0; i < files.length; i++) {
var file= files[i];
if(checkFileExtension(file) && checkFileSize(file)){ //checks the file for images and the size of the image
image = resizeImage(file);
formData.append('images[]', image);
}else{
formData.append(file[], file);
}
}
}
/*
*getting values & error handling...
*/
//appending values
formData.append('desc', description);
formData.append('personName', name);
var postrequest = new XMLHttpRequest();
postrequest.open('post', 'include/fileProcessing.php', true);
postrequest.send(formData);
postrequest.onload = function(){
var data = JSON.parse(postrequest.responseText);
if(data.result == 'true' ){
alert('Form has been submitted!');
}
php
$date = date('YmdHis');
if (isset($_FILES['images'])) {
$errors = [];
$path = '../images/uploads/';
$extensions = ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'pdf'];
$all_files = count($_FILES['images']['tmp_name']);
for ($i = 0; $i < $all_files; $i++) {
$original_Name = $_FILES['images']['name'][$i];
$file_name = $date .'_'.$original_Name;
$file_tmp = $_FILES['images']['tmp_name'][$i];
$file_type = $_FILES['images']['type'][$i];
$file_size = $_FILES['images']['size'][$i]/1024;
$file_ext = strtolower(end(explode('.', $_FILES['images']['name'][$i])));
if (!in_array($file_ext, $extensions)) {
$errors[] = 'Image type not allowed: ' . $original_Name . ' ' . $file_type;
}
if ($file_size > 2097152) {
$errors = 'Image size too large';
}
$file = $path . $file_name;
if (empty($errors)) {
move_uploaded_file($file_tmp, $file);
}
}
if ($errors) $rtVariables['picErrors'] = $errors;
}
/**check and upload files that are not images but too long to post**/
Any help would be greatly appreciated.
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 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 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