Create thumbnail from video without ffmpeg in PHP - php

I need to create thumbnail without ffmpeg because I have to deploy site on shared hosting and ffmpeg is not available on shared hosting.
Can someone suggest some solution?

If the video can be played back in the browser you could try using the Canvas feature of html5 to playback the video in a canvas and then post a still from that video to your server using javascript... Maybe you could even automate it, or if you only have a few dozen videos do it by hand...
The following is some jquery flavored javascript to upload a base64-encoded jpg in order to get you started. (Mashed up from several different projects, so untested and probably a security nightmare.)
<script>
var vidDOM = $('article').children('video');
var vid = vidDOM.get(2);
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
vidDOM.bind({
'paused':function () {
vid.width = canvas.width = vid.offsetWidth;
vid.height = canvas.height = vid.offsetHeight;
var $this = this;
ctx.drawImage($this, 0, 0, vid.width, vid.height);
uploadbase64();
}
})
function uploadbase64(){
canvasData = canvas.toDataURL("image/jpeg");
var ajax = new XMLHttpRequest();
ajax.open("POST",'ImageUpload.php?filename='+vidDOM.id,false);
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(canvasData);
}
</script>
And here is a bit of php to accept the upload.
<?php
$filename =$_GET['filename'];
if (file_get_contents('php://input')){
// Remove the headers (data:,) part.
$filteredData=substr(file_get_contents('php://input'), strpos(file_get_contents('php://input'), ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$decodedData=base64_decode($filteredData);
//create the file
if($fp = fopen( $filename, 'wb' )){
fwrite( $fp, $decodedData);
fclose( $fp );
} else {
echo "Could not create file.";
}
}
echo "Created image ".$filename;
?>

Related

php://input Uplaod image with image type

I'm implementing a drag and drop image uploader with ajax call,
I saw a tutorial on this and implemented like this, with this code I can save the image in .jpg format only! (or any one format that I specify in the code)
uploaded image saved in php://input folder before and we need to grab that image from that temp folder to save that in the server,
but they didn't tell anything to change image format as per the image type,
now I want to upload the image in the original format, how can I collect image information while it is uploading?
here is the code
<?php
$str =file_get_contents('php://input');
$filename = md5(time()).'.jpg';
$path = 'upload/'.$filename;
file_put_contents($path,$str);
echo $path;
here is some JS for taking the image and sending ajax request:
$(function(){
//select the drop container
var obj = $('.drop');
// dragover event listener
obj.on('dragover',function(e){
e.stopPropagation();
e.preventDefault();
$(this).css('border',"2px solid #16a085");
});
//drop event listener
obj.on('drop',function(e){
e.stopPropagation();
e.preventDefault();
$(this).css('border',"2px dotted #bdc3c7");
//get the files
var files = e.originalEvent.dataTransfer.files;
var file =files[0];
//console.log(file);
//upload data using the xhr object
upload(file);
});
function upload(file){
//create xhr object
xhr = new XMLHttpRequest();
//initiate request
xhr.open('post','drop.php',true);
//set headers
xhr.setRequestHeader('Content-Type',"multipart/form-data");
xhr.setRequestHeader('X-File-Name',file.fileName);
xhr.setRequestHeader('X-File-Size',file.fileSize);
xhr.setRequestHeader('X-File-Type',file.fileType);
//send the file
xhr.send(file);
}
});
Finally, I fixed this problem.
there was no problem with PHP to catch headers, as Magnus Eriksson said $_SERVER['HTTP_X_FILE_TYPE'] works fine, but problem was while sending ajax header we set header type and size wrong.
i logged file data and find type and size but i set header as fileType and fileSize
changed the code and here is the code before and after :
BEFORE: AJAX request:
//set headers
xhr.setRequestHeader('Content-Type',"multipart/form-data");
xhr.setRequestHeader('X-File-Name',file.fileName);
xhr.setRequestHeader('X-File-Size',file.fileSize);
xhr.setRequestHeader('X-File-Type',file.fileType);
and PHP:
$str =file_get_contents('php://input');
$filename = md5(time()).'.jpg';
$path = 'upload/'.$filename;
file_put_contents($path,$str);
echo $path;
AFTER: AJAX request:
//set headers
xhr.setRequestHeader('Content-Type',"multipart/form-data");
xhr.setRequestHeader('X-File-Name',file.fileName);
xhr.setRequestHeader('X-File-Size',file.size);
xhr.setRequestHeader('X-File-Type',file.type);
and PHP:
$str =file_get_contents('php://input');
$ext = $_SERVER['HTTP_X_FILE_TYPE'];
$e = explode("/",$ext);
$ext = $e[1];
$filename = md5(time()).'.'.$ext;
$path = 'upload/'.$filename;
file_put_contents($path,$str);
echo $path;
this code is working fine :)

Converting file upload to binary, post to server and save file using PHP

I am working with an app where I am unable to post the File to the server. Therefor I have chose to send it as a string to the server, and remake it to a file using PHP. Below is the javascript code I am using to convert the image to a string.
var file = document.getElementById("fileForUpload").files[0];
if (file) {
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function (evt) {
document.getElementById("fileContents").value = utf8_to_b64(evt.target.result);
}
reader.onerror = function (evt) {
document.getElementById("fileContents").value = "error reading file";
}
}
function utf8_to_b64(str) {
return window.btoa(unescape(encodeURIComponent(str)));
}
On the server side I'm doing this
header("Content-type: image/png");
$data = preg_replace('/\s+/', '', $data);
echo base64_decode($data);
exit;
But it says that the image cannot be displayed because it contains errors.
Can you please tell me what I am doing wrong here? I am correctly receiving the Base64 encoded string to the server.
Edit
Please note that I am trying to post the string through an HTML form.
Easy:
$imagedata = file_get_contents("/path/to/image.jpg");
// alternatively specify an URL, if PHP settings allow
$base64 = base64_encode($imagedata);
bear in mind that this will enlarge the data by 33%, and you'll have problems with files whose size exceed your memory_limit.

sending an uploaded PDF file via POST is becoming corrupt

Im trying to send a pdf file uploaded using JQ to a PHP file which uses CLI and pdf2svg to convert it to an svg file, with the eventual aim to return that svg file so that it can be placed into svg editor.
Currently i have this:
In svg-editor.js:
if(file.type.indexOf("pdf") != -1){
//convert to svg
//load svg string
var reader = new FileReader();
reader.onloadend = function(e) {
$.post("pdfuploads/pdfconvert.php", { 'pdf[]': [e.target.result] })
.done(function(data){
alert("Data Loaded: " + data );
svgCanvas.importSvgString(data, true);
svgCanvas.ungroupSelectedElement()
svgCanvas.ungroupSelectedElement()
svgCanvas.groupSelectedElements()
svgCanvas.alignSelectedElements("m", "page")
svgCanvas.alignSelectedElements("c", "page")
});
};
reader.readAsText(file);
}
The above checks the extension of the file being loaded, if its pdf then it posts it to the php file. (all working fine)
In my php file (its being tied in with drupal):
<?php
$dir = getcwd();
define('DRUPAL_ROOT', $_SERVER['DOCUMENT_ROOT']); //added to make sure its defined as we're outside the use of index.php
chdir(DRUPAL_ROOT);
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
chdir($dir);
global $base_url;
$time = microtime();
$handle = fopen("pdfupload-".$time.".pdf", "wb");
if (fwrite($handle, file_get_contents($_POST['pdf'][0])) === FALSE) {
$error = "Cannot write to file";
exit;
}
fclose($handle);
//$file = file_put_contents('pdfupload-'.$time.'.pdf', $_POST['pdf'][0]);
$svg = exec("/usr/local/bin/pdf2svg pdfupload-".$time.".pdf output_page-".$time."%d.svg all");
cg_utils_watch('file pdf value','', $error);
cg_utils_watch('file svg value','', $svg);
echo "<pre>";
print_r($svg);
echo "</pre>";
return $svg;
Ignore the logging and the fact that $svg doesnt return the svg file --
The pdf stream is taken from post, and saved. Unfortunalty someware between upload and saving on the server the pdf file becomes corrupted. It saves a pdf file, but when opening that file its empty, the end result being the svg file thats written to the server in the exec() is also empty.
Does anyone have any ideas / know any better way of doing this?
ok, so turns out that mkl in the comments above was right, the issue was with the reader.readAsText(file) line.
This was fireing before the post, so the PDF file was being posted as text.
following this: http://www.develop.com/htmlfivefileapi i changed the JQ to the following:
if(file.type.indexOf("pdf") != -1){
//convert to svg
//load svg string
var reader = new FileReader();
reader.onloadend = function(e) {
$.post("pdfuploads/pdfconvert.php", { 'pdf[]': [e.target.result] })
.done(function(data){
alert("Data Loaded: " + data );
svgCanvas.importSvgString(data, true);
svgCanvas.ungroupSelectedElement()
svgCanvas.ungroupSelectedElement()
svgCanvas.groupSelectedElements()
svgCanvas.alignSelectedElements("m", "page")
svgCanvas.alignSelectedElements("c", "page")
});
};
reader.readAsDataURL(file);
}
and it now works like a charm :)

Are canvas.toDataURL compatible with PHP's base64_decode?

My problem is as follows...
I have a screen in which the user can select a PNG image from its computer, using this:
<input id='icon' type='file' accept='image/png' style='width:400px; height:20px' onchange='llenarThumbnail(this)'>
<img id='thumb' src='#'>
When the user selects the image, a thumbnail is shown automatically, using onclick='llenar Thumbnail(this)', like this:
function llenarThumbnail(input){
if (input.files && input.files[0]){
var reader = new FileReader();
reader.onload = function (e){
$('#thumb').attr('src', e.target.result).width(48).height(48);
};
reader.readAsDataURL(input.files[0]);
}
}
Then, when the user clicks on the proper button to upload the image (not a submit button), I do the following to encode the image into Base64:
function getBase64Image(img){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
console.log(dataURL);
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
Then, using AJAX I send this encoded image data to the server, and a PHP script does the following:
$binary=base64_decode($imagen_data);
header('Content-Type: bitmap; charset=utf-8');
$file = fopen($icono, 'wb');
fwrite($file, $binary);
fclose($file);
As I was printing diferent alerts along the process, I could see that the encoding was performing (i'm not so sure if correctly or not), and PHP receives the data and creates the PNG file, but when I open the image, the image is empty, there's no data... Thats why I'm asking if this to methods are compatible... I guess they are because they're both Base64... But if its not this, then what am i doing wrong???
Please, I'm tired of looking for this all over the internet! I need some answers! Thank you!
Without seeing your ajax POST, here's a Wild Guess:
Try leaving the prefix on until the URL gets to php.
Which php server are you using?
Some other usual gotchas:
Make sure you have properly set up your upload directory.
Make sure you have permissions set properly on the upload directory.
Client Side:
// create a dataUrl from the canvas
var dataURL= canvas.toDataURL();
// post the dataUrl to php
$.ajax({
type: "POST",
url: "upload.php",
data: {image: dataURL}
}).done(function( respond ) {
// you will get back the temp file name
// or "Unable to save this image."
console.log(respond);
});
Server File: upload.php
<?php
// make sure the image-data exists and is not empty
// php is particularly sensitive to empty image-data
if ( isset($_POST["image"]) && !empty($_POST["image"]) ) {
// get the dataURL
$dataURL = $_POST["image"];
// the dataURL has a prefix (mimetype+datatype)
// that we don't want, so strip that prefix off
$parts = explode(',', $dataURL);
$data = $parts[1];
// Decode base64 data, resulting in an image
$data = base64_decode($data);
// create a temporary unique file name
$file = UPLOAD_DIR . uniqid() . '.png';
// write the file to the upload directory
$success = file_put_contents($file, $data);
// return the temp file name (success)
// or return an error message just to frustrate the user (kidding!)
print $success ? $file : 'Unable to save this image.';
}
I could not get markE solution to work, had to change the data modification :
From :
$parts = explode(',', $dataURL);
$data = $parts[1];
$data=base64_decode($data)
To :
$img = str_replace('data:image/png;base64,', '', $dataURL);
$img = str_replace(' ', '+', $img);
$data=base64_decode($img);
Method from

Send bitmap data from Flex to Php

I want to save a screenshot from my Flex app on the Webserver (LAMP).
Here is the Flex code:
private function getBitmapData( target : UIComponent ) : BitmapData
{
var bd : BitmapData = new BitmapData( target.width, target.height );
var m : Matrix = new Matrix();
bd.draw( target, m );
return bd;
}
Now, how do I send / receive this data to the server?
You are going to have to use a HttpService to post the data to a page on your website. When I implemented this I posted the Image data as a Base64 encoded string to a PHP page that used the GD library to save it to a png file on the server. Here is a simplified example of what my code looked like
Flex Code
public function saveImg():void{
var bd:BitmapData = new BitmapData(mycanvas.width,mycanvas.height);
bd.draw(mycanvas);
var ba:ByteArray = PNGEncoder.encode(bd);
var encoded:String = Base64.encodeByteArray(ba);
var objSend:Object = new Object;
objSend.data = encoded;
objSend.filename = _imgResult;
writeImage.send(objSend);
}
<mx:HTTPService id="writeImage" url="/saveImage.php" method="POST" resultFormat="text" result="resultHandler(event)"/>
PHP File (saveImage.php)
<?php
//check for the posted data and decode it
if (isset($_POST["data"]) && ($_POST["data"] !="")){
$data = $_POST["data"];
$data = base64_decode($data);
$im = imagecreatefromstring($data);
}
//make a file name
$filename = "test"
//save the image to the disk
if (isset($im) && $im != false) {
$imgFile = "/etc/www/html/".$filename.".png";
//delete the file if it already exists
if(file_exists($imgFile)){
unlink($imgFile);
}
$result = imagepng($im, $imgFile);
imagedestroy($im);
echo "/".$filename.".png";
}
else {
echo 'Error';
}
?>
On the flex side I am using the Base64Encode utilty from dynamicflash, but now that there is one built into flex you could use that instead. In your php config you will need to make sure you have the GD library enabled so that you can save the image.
Of course this is a very simple example and does not take into account all the error handling and security concerns needed, but should provide you a good base to get going with.

Categories