Hoping that someone will be able to tell me where Im going wrong here .
Im using Dropzonejs to allow people to drop files for storage online, I have 8 zones on one page, each used for a different category, when someone drops a file they are saved with additional data depending on which zone they were dropped in for later retrieval .. this all works fine.
I then wanted each zone to show the thumbnails for each of the files on the server under its category on page refresh, this is where I get problems, using the follwing code I get all my files being shown in the bottom zone, and the others are empty. Its obviously a problem with the code that fetches current files and makes the thumbnails, but Im lost as to why.
If I only have one instance on a page it all works fine.
Heres the code I use to setup and instantiate each dropzone instance.
Dropzone.options.dzdiag = {
url: "upload.php",
previewsContainer: "#dzdiag",
init: function() {
thisDropzone = this;
filetype = "diagnostic";
var propid = <?php echo $id; ?>; // set value to current property id
$.get('upload.php?propid='+propid+'&filetype='+filetype, function(data) { // get exisitng files and thumbnail
$.each(data, function(key,value){
var mockFile = { name: value.name, size: value.size, fileid: value.fileid, };
thisDropzone.options.addedfile.call(thisDropzone, mockFile);
var pattern = /\.(gif|jpg|jpeg|tiff|png)$/i;
if( pattern.test(value.name)){
thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/"+value.name);
}
});
});
thisDropzone.on("sending", function(file, xhr, formData) {
formData.append("propid", propid);
formData.append("filetype", filetype);
});
thisDropzone.on("success", function(file, serverack) {
file.fileid = serverack;
});
thisDropzone.on("removedfile", function(file) {
var delid = file.fileid;
$.post('upload.php?delid='+delid);
});
}
};
$("#dzdiag").dropzone();
Simply changing the previewsContainer (on not specifying it) for each zone should get you what you want.
Related
Does anybody know how to post the cropped image to PHP using darkroomjs?
Link here: https://github.com/MattKetmo/darkroomjs
I want to upload the cropped image to the server. Also, how do I set the location of the cropped image to appear in a different HTML element.
For example, if when I hit the crop button in darkroomjs it updates the cropper canvas with the new image. How do I make it also move the cropped image to another HTML element on the page?
Thanks in advance.
I have a working version of this - it took me an hour or so to figure out and steal some other peoples suggestions mixed it all together and aletered a few bits here and there and here it is...
I parse the filename into JavaScript from my html from a hidden input type that was popuated by php ($('#profile_pic_filename').val();)
if($('.image-container.target').length){
$('#member_portrait').change(function(){
$('#member_photo_hidden_file').val("");
});
var pic_name = $('#profile_pic_filename').val();
var dkrm = new Darkroom('#target', {
// Size options
minWidth: 100,
minHeight: 100,
maxWidth: 600,
maxHeight: 500,
ratio: 4/3,
backgroundColor: '#000',
// Plugins options
plugins: {
//save: false,
crop: {
quickCropKey: 67, //key "c"
//minHeight: 50,
//minWidth: 50,
//ratio: 4/3
},
save: {
callback: function() {
this.darkroom.selfDestroy(); // Cleanup
var newImage = dkrm.canvas.toDataURL();
$.ajax({
type : "POST",
dataType : "html",
url : base_url+'ajax/updateProfilePic',
data : {
'newImage' : newImage,
'imageName' : pic_name
}
})
.done(function(response){
response = $.parseJSON(response);
var status = response.status;
var data = response.data;
if(status === "success"){
location.reload();
}else{
alert(data);
}
});
}
}
},
// Post initialize script
initialize: function() {
var cropPlugin = this.plugins['crop'];
// cropPlugin.selectZone(170, 25, 300, 300);
cropPlugin.requireFocus();
}
});
}
in my ajax file i take the image and decode the base 64 version of the image and then parse that into a function with the filname that then overwrites the original file and hey presto the image has been replaced on the server.
$newImage = '';
$imageName = '';
if(isset($_POST['newImage'])){
$newImage = $_POST['newImage'];
}
if(isset($_POST['imageName'])){
$imageName = $_POST['imageName'];
}
function saveProfilePic($filename,$filecontent){
if (strlen($filename)>0){
$folderPath = '/home/xxxxxxxxxxxxx/public_html/images/uploads/_mem_photo/';
if (!file_exists($folderPath)) {
mkdir($folderPath);
}
$file = #fopen($folderPath.$filename,"w");
if($file != false){
fwrite($file,$filecontent);
fclose($file);
return 1;
}
return -2;
}
return -1;
}
$data = explode(',',$newImage);
$final = base64_decode($data[1]);
$fileSavingResult = saveProfilePic($imageName, $final);
if($fileSavingResult == 1){
$return = array("status"=>"success", "data"=>"File was saved!");
}
else if($fileSavingResult == -2){
$return = array("status"=>"fail", "data"=>"An error occured during saving file!");
}
else if($fileSavingResult == -1){
$return = array("status"=>"fail", "data"=>"Wrong file name!");
}
echo json_encode($return);
I've just placed xxxxx into file path as I don't want to give up any server info.
If all is successfull you get a page reload and the newly transformed image loads on the page but if there is an error it will alert you.
Theoretically, in order to post the image to PHP you want to get the src contents of the <img> element which is stored in Base64 in the case of this plugin.
Once you grab that value using JQuery, you can send it to the server asynchronously using AJAX or by posting your form the regular way by putting the src contents into a hidden field somewhere. From that point you can use tools such as PHP's GD and Image functions or Intervention / Image to create an image file on the server from that Base64 data.
In your case, sending it asynchronously by just grabbing the <img src="base64img"> would probably be easiest.
$('#theForm').submit(function(event){
// preventDefault stops the regular synchronous submit from happening -- we don't want that. we want an async AJAX request
event.preventDefault();
var formData = $('#yourImgElement').attr('src');
var returnMessage = '';
$.post(site+'post/to/location', formData, function(response){
if(response.status){
returnMessage = 'Save Successful.';
} else {
returnMessage = 'Save Failed:\n\n';
for (i = 0; i < response.errors.length; i++) {
returnMessage += '- ' + response.errors[i] + '\n';
}
}
alert(returnMessage);
},'json');
return false; // return false to cancel form action
});
It's my understanding that cropping the image and saving it should reflect the changes within the Base64, but I personally and someone else is actually having problems with that.
In order to do the other stuff you want to do, you should be able to do it fairly easily with JQuery (look up restructuring the DOM). Just hook into the events:
// Post initialization method
initialize: function() {
// Active crop selection
this.plugins['crop'].requireFocus();
// Add custom listener
this.addEventListener('core:transformation', function() {
// THIS IS WHERE YOU WOULD THEN PERFORM DOM MANIPULATIONS USING JQUERY
});
}
You should be careful with moving the image after it's been edited, however. It could throw JavaScript errors if the plugin is expecting certain elements to be in certain locations.
UPDATED WITH SOLUTION:
======================
The src of the image will never change. In order to get the Base64 code of the edited image, you actually need to ask the canvas for it. Here is how you can do it:
// Plugins options
plugins: {
crop: {
//minHeight: 300,
//minWidth: 400,
//ratio: 4/3
},
save: {
callback: function() {
this.darkroom.selfDestroy(); // Turn off the bar and cleanup
var newImage = dkrm.canvas.toDataURL();
varThatStoresYourImageData = newImage;
}
}
}
Hi I'm trying to save an image to the apps properties as part of a JSON array but when i try to display it, the imageview appears blank. The image is grabbed from the phone's gallery when the Upload_pic button is clicked. Code below:
Upload_pic.addEventListener('click', function (e){
Upload_pic.setImage('/images/uploadPhoto2.png');
Titanium.Media.openPhotoGallery({
success: function(e){
console.log("typeof e.media -------- " + e.media);
ImageView=Ti.UI.createImageView({
image:e.media
}).toImage();
},
error: function(e){
alert("Error accessing photos");
Upload_pic.setImage('/images/uploadPhoto1.png');
},
cancel: function(e){
Upload_pic.setImage('/images/uploadPhoto1.png');
},
alowEditing:true,
mediaType:[Titanium.Media.MEDIA_TYPE_PHOTO]
});
});
and then I'm saving the image on this submit_btn click:
Submit_btn.addEventListener('click', function (e){
var filename = ID+"-ea.jpg";
bgImage = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, filename);
bgImage.write(ImageView);
if (bgImage.exists()) //File ever does not exist.
{
alert('file '+filename+' exists!!!');
// I am getting this alert
}
else
{
alert('file '+filename+' IS NOT exist(');
}
MyRecipe_info= {name: title_textField.value, ID:ID, Ingredients: ingredients_textField.value, numSteps:numSteps_textField.value, pic:bgImage, steps:numStepsArray};
Ti.App.Properties.setBool('MyRecipeAdded', true);
MyRecipes_data.push(MyRecipe_info);
Ti.App.Properties.setString('MyRecipesData', JSON.stringify(MyRecipes_data));
alert("Recipe added successfully!");
});
And then i am displaying it here:
MyRecipes_data=JSON.parse(Ti.App.Properties.getString('MyRecipesData'));
for(i=0;i<MyRecipes_data.length;i++){
var Pic = Titanium.UI.createImageView({
left: '5dp',
top:'20dp',
right:'15dp',
height: Ti.UI.SIZE,
bottom: '5dp',
image:MyRecipes_data[i].pic
});
}
Currently working on iOS, but code will need to work on Android in future. Using Titanium SDK 3.3.0.201407100905 and Titanium Classic
Problem was I needed to store the bgImage.nativePath
to store a image in property is bad habit as it takes much memory specially for android so i would suggest to store only image path in that array
or even if possible you should use database to store data instead of using Ti.Property.
Hope you get it.
I'm using dropzone.js and node.js to add an easy drag-and-drop interface for a user to upload up to 10 photos to server.
Here is my init function:
init: function(){
var photos = $('#property-photo').data('photos').split(',');
for (var i = 0; i < photos.length; i++) {
var photo = "/photo/" + photos[i];
var mockFile= {type: "image/*", name: 'photo', size: 1500};
this.addFile.call(this, mockFile);
this.options.thumbnail.call(this, mockFile, photo);
}
}
The thumbnail is shown but when i call listingDropzone.processQueue(); - it throws an error:
Failed to execute 'append' on 'FormData': No function was found that
matched the signature provided.
Only if i remove the image and add a new one it works.
Any ideas?
Dropzone can't upload a mock file. Mock file was already uploaded.
You can see this issue: https://github.com/enyo/dropzone/issues/418
Okey, so what I want to do is download multiple images stored in an JavaScript array in AngularJS. I have not found any way of doing this in the form of "pure" images like .png .jpg etc (although if anyone knows how to do this please let me know). So I have turned to trying to zip the images with the help of jszip.js according to the description here : http://viralpatel.net/blogs/create-zip-file-javascript/
<li ng-click="download()"><a>Save to harddrive</a></li>
So this is the code called when the user clicks "download":
photodice.controller('ProjectController', function($scope, imageFactory) {
$scope.images = imageFactory.getImages();
$scope.download = function() {
var zip = new JSZip();
for (var x in $scope.images) {
zip.folder("images").add("image" + x + ".png", $scope.images[x], {base64: true});
}
var content = zip.generate();
console.log("content = "+ content);
location.href="data:application/zip;base64," + content;
}
});
The problems occurs when the last line of code is executed, the browser crashes... I do not really understand how filedownloads work... Any suggestion or tips on what I should read up on would be greatly appreciated!
Update:
I tried using Downloadify to solve my problem... and added some code:
$scope.download = function() {
var zip = new JSZip();
for (var x in $scope.images) {
zip.folder("images").add("image" + x + ".jpg", $scope.images[x], {base64: true});
}
Downloadify.create('downloadify',{
filename: function(){
return "Images.zip";
},
data: function(){
return zip.generate();
},
onComplete: function(){
alert('Your File Has Been Saved!');
},
onCancel: function(){
alert('You have cancelled the saving of this file.');
},
onError: function(){
alert('You must put something in the File Contents or there will be nothing to save!');
},
transparent: false,
swf: 'downloadify.swf',
downloadImage: 'img/download.png',
width: 100,
height: 30,
transparent: true,
append: false,
dataType: 'base64'
});
And now I can save the zip file:)
HOWEVER I still have a problem... the files in the zip are corrupt...
Normal non corrupt images look like this:
"data:image/jpeg;base64,iVBORw0KGgoAhE... ...c8+ocAAAAORK5CYII="
If I upload "currupt" images to my site agian and check the scope of the images that are corrupt the data looks like this:
"data:image/jpeg;base64,dataimage/jpegbase64iVBORw0KA... ...RNgAK5CYII="
Alternatively I remove the {base64: true}:
"data:image/jpeg;base64,ZGF0YTppbWF... ...WT1JLNUNZSUk9" (no "=" at the end)
What can I do about this?
I'm putting the answer here for future reference (because it was buried in the comments).
The issue comes from $scope.images[x] which contains a string, "data:image/jpeg;base64,iVBORw0KGgoAhE... ...c8+ocAAAAORK5CYII=". JSZip interprets the data:image/jpeg;base64, part as base64 content and generates corrupted images. To remove this part, you can do the following :
var base64 = $scope.images[x];
var index = base64.indexOf(",");
if (index !== -1) {
base64 = base64.substring(index + 1, base64.length);
}
zip.folder("images").file("image" + x + ".jpg", base64, {base64: true});
Also, the add() method you use has been deleted in 2011 so you may want to update JSZip ! (but that may need some work : only folder() and remove() haven't changed between your version and the latest).
I'm using the jquery audio recording plugin jrecorder and I want to be able to change the audio file name by pushing a button. The script defines the file name with the 'host' variable. I want to be able to change that variable to "track01" by clicking button01 or "track02" by clicking button2. How would I go about doing this?
<script>
$.jRecorder(
{
host : 'acceptfile.php?filename=track00' ,
callback_started_recording: function(){callback_started(); },
callback_stopped_recording: function(){callback_stopped(); },
callback_activityLevel: function(level){callback_activityLevel(level); },
callback_activityTime: function(time){callback_activityTime(time); },
callback_finished_sending: function(time){ callback_finished_sending() },
swf_path : 'jRecorder.swf',
});
////Make buttons change save-file name
$("#button01").click(function(){
//CHANGE 'host' to 'acceptfile.php?filename=track01'
;});
$("#button02").click(function(){
//CHANGE 'host' to 'acceptfile.php?filename=track02'
;});
</script>
I managed to devise the solution by making changes in the Main.as script file and also in the jRecorder.js file. Following are six steps that you will need to achieve this.
Step -1
Go to https://github.com/sythoos/jRecorder and download everything in the flash-fla folder. Make sure you match the folder of the flash-fla folder structure EXACTLY on your local machine.
Step -2
Once you have done that, and if you haven't got it already, you're going to need to download Flash. I used the free 30 day trial to do this, you can also do the same.
Step 3. Open Main.as file and make following two changes:
Change : 1
Define a new string variable to contain file name
Change : 2
Add parameter in "jSendFileToServer" method
Step 4: Once the above changes are done, you need to open up the AudioRecorderCS4-1.0.fla file in Flash and export the movie (File -> Export -> Export Movie).
Step 5. Open jRecorder.js file and make following change:
Add parameter to sendData Method
Step 6. Open your HTML and make the change in the JS method which calls sendData
Add parameter in the sendData Method
Following are the code snippets, please note that I am pasting few lines of code before and after my changes by adding comments to the code which I have added/modified.
Main.as File
private var recorder:MicRecorder = new MicRecorder(waveEncoder);
private var recBar:RecBar = new RecBar();
private var maxTime:Number = 30;
//Start of addition by FaisalKhan
private var FileName:String = 'Hello.wav';
//End of addition by FaisalKhan
//Start of change 1 of 2 by Faisal
//public function jSendFileToServer():void
public function jSendFileToServer(file_name):void
//End of change 1 of 2 by Faisal
{
//Start of change 2 of 2 by FaisalKhan
FileName=file_name;
//End of change 2 of 2 by FaisalKhan
finalize_recording();
}
//functioon send data to server
private function finalize_recording():void
{
var _var1:String= '';
var globalParam = LoaderInfo(this.root.loaderInfo).parameters;
for (var element:String in globalParam) {
if (element == 'host'){
//Start of change by FaisalKhan
//_var1 = globalParam[element];
_var1 = globalParam[element]+FileName;
//End of change by FaisalKhan
}
}
ExternalInterface.call("$.jRecorder.callback_finished_recording");
if(_var1 != '')
{
var req:URLRequest = new URLRequest(_var1);
req.contentType = 'application/octet-stream';
req.method = URLRequestMethod.POST;
req.data = recorder.output;
var loader:URLLoader = new URLLoader(req);
ExternalInterface.call("$.jRecorder.callback_finished_sending");
}
}
jRecorder.js file change:
//function call to send wav data to server url from the init configuration
//Start of change by FaisalKhan
//$.jRecorder.sendData = function(){
$.jRecorder.sendData = function(file_name){
//getFlashMovie(jRecorderSettings['recorder_name']).jSendFileToServer();
getFlashMovie(jRecorderSettings['recorder_name']).jSendFileToServer(file_name);
//End of change by FaisalKhan
}
HTML Button click method change:
$('#SendRecordingDiv').click(function(){
//Start of change by FaisalKhan
//$.jRecorder.sendData($();
$.jRecorder.sendData($("#FileControl").val()+'.wav');
//End of change by FaisalKhan
});
Below is how, although I think you will still have issues because your $.jRecorder code is running as soon as the page loads, so by the time a user hits a button its too late. Maybe also consider putting that inside a function, and calling that function after they press the button.
<script>
function WhoSaysDearMe(saveFileName) {
$.jRecorder({
host : saveFileName ,
callback_started_recording: function(){callback_started(); },
callback_stopped_recording: function(){callback_stopped(); },
callback_activityLevel: function(level){callback_activityLevel(level); },
callback_activityTime: function(time){callback_activityTime(time); },
callback_finished_sending: function(time){ callback_finished_sending() },
swf_path : 'jRecorder.swf',
});
}
////Make buttons change save-file name
$("#button01").click(function(){
//CHANGE 'host' to 'acceptfile.php?filename=track01'
WhoSaysDearMe('acceptfile.php?filename=track01');
;});
$("#button02").click(function(){
//CHANGE 'host' to 'acceptfile.php?filename=track02'
WhoSaysDearMe('acceptfile.php?filename=track02');
;});
</script>