How to convert an image to base64 in GAE php - php

as file_open_contents() is disabled in GAE php.
Any effective way to convert a image file (say png / jpg) and display image in dataurl to hide the filename and path

Let's try this :
HTML :
<input type="file" id="fileToUpload" name="fileToUpload" multiple="multiple">
Javascript :
$("#fileToUpload").change(function(event) {
$.each(event.target.files, function(index, file) {
var reader = new FileReader();
reader.onload = function(event) {
object = {};
object.filename = file.name;
object.data = event.target.result;
files.push(object);
datasrc = event.target.result;
var inlineImgD = "<img src="+datasrc+">";
};
reader.readAsDataURL(file);
});
});

Related

jquery ajax file upload with progressbar uploading same file multiple times

i am creating media-bank where user can upload media files and can reuse later
image,audio and videos can be uploaded with the following options
image upload from pc, specify link
audio upload from pc, specify link
video upload from pc, youtube url, facebook embed code
separate forms are created in tabbed layout with class="FormUpload"
upload from pc forms has <input type="file" name="file".../>
while all other forms has <textarea name="file" ...>
my database table looks like
[id, file, type, src,...]
[1, pic.png, image, pc,...]
[2, http://domin/img.png, image, link,...]
$('body').on('submit','.FormUpload',function(e){
e.preventDefault();
var pr = $(this).parents('.tabPanes').find('.progressBar');
var lbl = $(this).parents('.tabPanes').find('.percentLabel');
var url = $(this).attr('action');
var data = new FormData();
if($(this).find('#txtFile[type="file"]').length === 1 ){
data.append('file', $(this).find( '#txtFile' )[0].files[0]);
}else{
data.append('file', $(this).find('#txtFile' ).val());
}
data.append('type',$(this).find('#txtType').val());
data.append('src',$(this).find('#txtSrc').val());
data.append('title',$(this).find('#txtTitle').val());
data.append('tags',$(this).find('#txtTags').val());
if($(this).find('#txtFile[type="file"]').length === 1){//if file is being uploaded from pc
pr.val(100);
fileForm(url,data,pr,lbl);
}else{//else link is provided
linkForm(url,data,pr,lbl);
pr.val(0);
}
return false;
});
function fileForm(url,data,pr,lbl){
`enter code here`$.ajax({
url : url,
type: "POST",
data : data,
contentType: false,
cache: false,
processData:false,
xhr: function(){
//upload Progress
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
pr.val(percent);
}, false);
}
return xhr;
},
mimeType:"multipart/form-data",
}).done(function(res){ //
frm[0].reset();
lbl.html(res);
});
linkForm() also looks like fileForm()
the issue is when I upload image from PC it uploads the same image 3-times some time 5-times in folder as well as database.
I debuged and noticed network tab, ajax request to php file is also being sent multiple times.
tried to replace all jquery code by the following but still same issue but this time frequency looks reduced
$('body').on('submit','.FormUpload',function(e){
e.preventDefault(); //prevent form normal submition
//get progressbar label url_to_hit and form_reference into variables to be used below
var pr = $(this).parents('.tabPanes').find('.progressBar');
var lbl = $(this).parents('.tabPanes').find('.percentLabel');
var url = $(this).attr('action');
var frm = $(this);
//populate formdata
var data = new FormData();
if(frm.find('#txtFile[type="file"]').length === 1 ){
data.append('file', frm.find( '#txtFile' )[0].files[0]);
}else{
data.append('file', frm.find('#txtFile' ).val());
}
data.append('type',frm.find('#txtType').val());
data.append('src',frm.find('#txtSrc').val());
data.append('title',frm.find('#txtTitle').val());
data.append('tags',frm.find('#txtTags').val());
//prepare ajax and callback functions
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener('progress',function(evt){
var percentage = (evt.loaded/evt.total)*100;
pr.val(Math.round(percentage));
lbl.html(Math.round(percentage)+'% uploaded.');
},false);
ajax.addEventListener('load',function(evt){
lbl.html(evt.target.responseText);
pr.val(0);
},false);
ajax.addEventListener('error',function(evt){
lbl.html('upload failed');
pr.val(0);
},false);
ajax.addEventListener('abort',function(evt){
lbl.html('upload aborted');
pr.val(0);
},false);
ajax.open('POST',url);
ajax.send(data);
//again stop form submition (optional)
return false;
});

Saving a base 64 image creates a blank image in PHP

First here's my client side code:
$("#fileToUpload").on("change", function(){
var filesToUpload = document.getElementById("fileToUpload");
var file = filesToUpload.files[0];
var img = new Image(600,400);
var reader = new FileReader();
reader.onload = function(e){
img.src = e.target.result;
}
reader.readAsDataURL(file);
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
img.onload = function(){
canvas.width = 600;
canvas.height = 400;
ctx.drawImage(img,0,0,canvas.width,canvas.height);
}
var dataURL = canvas.toDataURL("image/jpg");
var data = new FormData();
data.append("image", dataURL);
var xhttp = new XMLHttpRequest;
xhttp.open("POST", "test.php", true);
xhttp.send(data);
})
And here's my php code:
$imageArr = explode(',', $_POST['image']);
$image = base64_decode($imageArr[1]);
file_put_contents('image.jpg',$image);
I'm resizing the image on the client side and then sending it as a data url to php to then be saved as an image.
When I save an image it creates a blank image on my server. BUT when I save another image without refreshing the page it saves the previous image in it's place and this time correctly. This is beyond me, can someone please shed some light?
You are sending the image before it is loaded. Your img.onload function is executed after xhttp.send(data). When you upload one more time it gets previous image which is already loaded.
Try following:
$("#fileToUpload").on("change", function(){
var filesToUpload = document.getElementById("fileToUpload");
var file = filesToUpload.files[0];
var img = new Image(600,400);
var reader = new FileReader();
reader.onload = function(e){
img.src = e.target.result;
}
reader.readAsDataURL(file);
var canvas = document.getElementById("canvas");
canvas.width = 600;
canvas.height = 400;
var ctx = canvas.getContext('2d');
img.onload = function(){
ctx.drawImage(img,0,0,canvas.width,canvas.height);
var dataURL = canvas.toDataURL("image/jpg");
var data = new FormData();
data.append("image", dataURL);
var xhttp = new XMLHttpRequest;
xhttp.open("POST", "test.php", true);
xhttp.send(data);
}
})
A possibility to keep in mind: Since everything on client side is setup in the file input's onChange event handler, maybe some setup code is launched in the wrong order and/or not in time to be used as intended? Then, when invoking the onChange event again, resources are already in place /has already been initialized and the image gets displayed as intended.
It's just a theory. To investigate, try to move initializations out of the event handler scope.

I want to make this similar HTML structure in jQuery function dynamically and append to html tag id="images"

I am uploading images and want to show separate progress bar for each image.
This kind of similar structure I want to create dynamically in jQuery. Here I m trying to create img element uploaded by input file and want to create html container classname 'preview' and put into already created #images tag by using jQuery. Will you please anyone fix it? so frustrated and thanks in advance to all intelligent brains here.
<div id="images"> // already exist
<div class="preview" id="rand">
<img src="background/balance.jpg" id="rand"/>
<div class="progressbar" id="rand">
</div> // this is the preview container to create and put by dynamically in jQuery function
</div>
this is my jQuery function.
function handleFile(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var fileReader=new FileReader();
var rand = Math.floor((Math.random()*100000)+3); /* this is created for assign id attribute to div and img tag to differentiate each other */
var imageElem=document.createElement("img");
imageElem.id=rand;
var div = document.createElement('div');
div.className = 'preview';
div.id = rand;
var progress = document.createElement('div');
progress.className='progressbar';
progress.id=rand;
fileReader.onload = (function(img)
{
return function(e)
{
img.src = e.target.result;
};
}) (imageElem);
/* here I am trying to create that structure */
document.getElementById("images").appendChild(imageElem); /* and need to append here */
fileReader.readAsDataURL(file);
// document.getElementById("areatext").style.display = "none";
document.getElementById("submit1").style.display = "block";
document.getElementById("submit2").style.display = "block";
uploadFile(file,rand);
}
}
function uploadFile(file,rand) {
var xhr = new Array();
xhr[rand] = new XMLHttpRequest();
var formData = new FormData();
formData.append('myFile[]',file);
xhr[rand].upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
$(".progressbar[id='"+rand+"']").css("width",(e.loaded / e.total) * 100 + "%");
}
}, false);
xhr[rand].open("POST", "drop.php");
xhr[rand].overrideMimeType('text/plain; charset=x-user-defined-binary');
xhr[rand].send(formData);
}

PHP Image Compression Before Upload [duplicate]

I need to provide a means for a user to upload photos to their web site in jpeg format. However, the photos are very large in original size, and I would like to make the resize before upload option very effortless for the user. It seems my only options are a client side application that resizes the photos before uploading them via a web service, or a client side JavaScript hook on the upload operation that resizes the images. The second option is very tentative because I don't have a JavaScript image resizing library, and it will be difficult to get the JavaScript to run my current resize tool, ImageMagick.
I'm sure this is not too uncommon a scenario, and some suggestions or pointers to sites that do this will be appreciated.
In 2011, we can know do it with the File API, and canvas.
This works for now only in firefox and chrome.
Here is an example :
var file = YOUR_FILE,
fileType = file.type,
reader = new FileReader();
reader.onloadend = function() {
var image = new Image();
image.src = reader.result;
image.onload = function() {
var maxWidth = 960,
maxHeight = 960,
imageWidth = image.width,
imageHeight = image.height;
if (imageWidth > imageHeight) {
if (imageWidth > maxWidth) {
imageHeight *= maxWidth / imageWidth;
imageWidth = maxWidth;
}
}
else {
if (imageHeight > maxHeight) {
imageWidth *= maxHeight / imageHeight;
imageHeight = maxHeight;
}
}
var canvas = document.createElement('canvas');
canvas.width = imageWidth;
canvas.height = imageHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
// The resized file ready for upload
var finalFile = canvas.toDataURL(fileType);
}
}
reader.readAsDataURL(file);
There is multiple-technology-capable Plupload tool which declares that it can do resizing before upload, but I haven't tried it yet. I have also find a suitable answer in my question about binary image handling javascript libs.
You have several options:
Java
ActiveX (only on windows)
Silverlight
Flash
Flex
Google Gears (the most recent version is capable of resizing and drag and drop from your desktop)
I've done a lot of research looking for a similar solution to what you have described and there a lot of solutions out there that vary a lot in quality and flexibility.
My suggestion is find a solution which will do 80% of what you need and customize it to suit your needs.
I think you need Java or ActiveX for that. For example Thin Image Upload
What jao and russau say is true. The reason being is JavaScript does not have access to the local filesystem due to security reasons. If JavaScript could "see" your image files, it could see any file, and that is dangerous.
You need an application-level control to be able to do this, and that means Flash, Java or Active-X.
Unfortunately you won't be able to resize the images in Javascript. It is possible in Silverlight 2 tho.
If you want to buy something already done: Aurigma Image Uploader is pretty impressive - $USD250 for the ActiveX and Java versions. There's some demos on the site, I'm pretty sure facebook use the same control.
Here some modifications to feed tensorflow.js(soo fast with it!!) with resized and cropped image (256x256px), plus showing original image under cropped image, to see what is cut off.
$("#image-selector").change(function(){
var file = $("#image-selector").prop('files')[0];
var maxSize = 256; // well now its minsize
var reader = new FileReader();
var image = new Image();
var canvas = document.createElement('canvas');
var canvas2 = document.createElement('canvas');
var dataURItoBlob = function (dataURI) {
var bytes = dataURI.split(',')[0].indexOf('base64') >= 0 ?
atob(dataURI.split(',')[1]) :
unescape(dataURI.split(',')[1]);
var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
var max = bytes.length;
var ia = new Uint8Array(max);
for (var i = 0; i < max; i++)
ia[i] = bytes.charCodeAt(i);
return new Blob([ia], { type: mime });
};
var resize = function () {
var width = image.width;
var height = image.height;
if (width > height) {
if (width > maxSize) {
width *= maxSize / height;
height = maxSize;
}
} else {
if (height > maxSize) {
height *= maxSize / width;
width = maxSize;
}
}
if (width==height) { width = 256; height = 256; }
var posiw = 0;
var posih = 0;
if (width > height) {posiw = (width-height)/2; }
if (height > width) {posih = ((height - width) / 2);}
canvas.width = 256;
canvas.height = 256;
canvas2.width = width;
canvas2.height = height;
console.log('iw:'+image.width+' ih:'+image.height+' w:'+width+' h:'+height+' posiw:'+posiw+' posih:'+posih);
canvas.getContext('2d').drawImage(image, (-1)*posiw, (-1)*posih, width, height);
canvas2.getContext('2d').drawImage(image, 0, 0, width, height);
var dataUrl = canvas.toDataURL('image/jpeg');
var dataUrl2 = canvas2.toDataURL('image/jpeg');
if ($("#selected-image").attr("src")) {
$("#imgspeicher").append('<div style="width:100%; border-radius: 5px; background-color: #eee; margin-top:10px;"><div style="position: relative; margin:10px auto;"><img id="selected-image6" src="'+$("#selected-image").attr("src")+'" style="margin: '+document.getElementById('selected-image').style.margin+';position: absolute; z-index: 999;" width="" height=""><img id="selected-image2" src="'+$("#selected-image2").attr("src")+'" style="margin: 10px; opacity: 0.4;"></div><div class="row" style="margin:10px auto; text-align: left;"> <ol>'+$("#prediction-list").html()+'</ol> </div></div>');
}
$("#selected-image").attr("src",dataUrl);
$("#selected-image").width(256);
$("#selected-image").height(256);
$("#selected-image").css('margin-top',posih+10+'px');
$("#selected-image").css('margin-left',posiw+10+'px');
$("#selected-image2").attr("src",dataUrl2);
$("#prediction-list").empty();
console.log("Image was loaded, resized and cropped");
return dataURItoBlob(dataUrl);
};
return new Promise(function (ok, no) {
reader.onload = function (readerEvent) {
image.onload = function () { return ok(resize()); };
image.src = readerEvent.target.result;
};
let file = $("#image-selector").prop('files')[0];
reader.readAsDataURL(file);});});
Html implementation:
<input id ="image-selector" class="form-control border-0" type="file">
<div style="position: relative; margin:10px auto; width:100%;" id="imgnow">
<img id="selected-image" src="" style="margin: 10px; position: absolute; z-index: 999;">
<img id="selected-image2" src="" style="margin: 10px; opacity: 0.4;">
</div>
Also not resize to a maximum width/height, but to minimum. We get a 256x256px square image.
Pure JavaScript solution. My code resizes JPEG by bilinear interpolation, and it doesn't lose exif.
https://github.com/hMatoba/JavaScript-MinifyJpegAsync
function post(data) {
var req = new XMLHttpRequest();
req.open("POST", "/jpeg", false);
req.setRequestHeader('Content-Type', 'image/jpeg');
req.send(data.buffer);
}
function handleFileSelect(evt) {
var files = evt.target.files;
for (var i = 0, f; f = files[i]; i++){
var reader = new FileReader();
reader.onloadend = function(e){
MinifyJpegAsync.minify(e.target.result, 1280, post);
};
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
You can resize the image in the client-side before uploading it using an image processing framework.
Below I used MarvinJ to create a runnable code based on the example in the following page:
"Processing images in client-side before uploading it to a server"
Basically I use the method Marvin.scale(...) to resize the image. Then, I upload the image as a blob (using the method image.toBlob()). The server answers back providing a URL of the received image.
/***********************************************
* GLOBAL VARS
**********************************************/
var image = new MarvinImage();
/***********************************************
* FILE CHOOSER AND UPLOAD
**********************************************/
$('#fileUpload').change(function (event) {
form = new FormData();
form.append('name', event.target.files[0].name);
reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.onload = function(){
image.load(reader.result, imageLoaded);
};
});
function resizeAndSendToServer(){
$("#divServerResponse").html("uploading...");
$.ajax({
method: 'POST',
url: 'https://www.marvinj.org/backoffice/imageUpload.php',
data: form,
enctype: 'multipart/form-data',
contentType: false,
processData: false,
success: function (resp) {
$("#divServerResponse").html("SERVER RESPONSE (NEW IMAGE):<br/><img src='"+resp+"' style='max-width:400px'></img>");
},
error: function (data) {
console.log("error:"+error);
console.log(data);
},
});
};
/***********************************************
* IMAGE MANIPULATION
**********************************************/
function imageLoaded(){
Marvin.scale(image.clone(), image, 120);
form.append("blob", image.toBlob());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<form id="form" action='/backoffice/imageUpload.php' style='margin:auto;' method='post' enctype='multipart/form-data'>
<input type='file' id='fileUpload' class='upload' name='userfile'/>
</form><br/>
<button type="button" onclick="resizeAndSendToServer()">Resize and Send to Server</button><br/><br/>
<div id="divServerResponse">
</div>

plupload height and width over 8000x8000px

I got a probleme with plupload when the height or the width of my image is to height(8000px * 8000px)
plupload upload the image but he return me full black after the resize.
I look for get the dimension of the image before the parsing by plupload.
thx.
Thx it's help me and it's work fine !
uploader.bind('FilesAdded', function(up, files) {
files = jQuery("#"+uploader.id+"_html5").get(0).files;
jQuery.each(files, function(i, file) {
var reader = new FileReader();
reader.onload = (function(e) {
var image = new Image();
image.src = e.target.result;
image.onload = function() {
if(this.width < 8000 && this.height < 8000){
uploader.start();
}else{
var message_max_picture = "<?php echo __('Vous avez dépassé les dimensions autorisées pour l\'image '); ?>";
display_error_serv('Erreur', message_max_picture, '');
uploader.removeFile(myfile);
}
}
};
});
reader.readAsDataURL(file);
});
could be usefull to know, that to access width and heigth without thumbnail an image you can do this:
uploader.bind('FilesAdded', function(up, files) {
files = jQuery("#"+uploader.id+"_html5").get(0).files;
jQuery.each(files, function(i, file) {
var reader = new FileReader();
reader.onload = (function(e) {
var image = new Image();
image.src = e.target.result;
image.onload = function() {
// access image size here using this.width and this.height
}
};
});
reader.readAsDataURL(file);
}
}

Categories