Salvare imagine Canvas pe server

Discutii si intrebari legate de scripturi si functii JavaScript, jQuery si Ajax, cod JavaScript in general.
andras
Mesaje:430

Salvare imagine Canvas pe server

Salut,
Vreau sa salvez imaginea JPG pe server dar nu pune nimic in fisierul jpg. Am incercat (simplificat):

Cod: Selectaţi tot

<script>  
var dia = document.getElementById(cnv_id).toDataURL("image/jpeg", 1.0); // nu merge nici simplu toDataURL() fara parametri
  savepng(dia);
</script>
in care #cnv_id este id-ul canvas-ului. Mai departe, cu functia savepng(dia) transfer acest paramentru catre ajax, iar in fisierul apelat cu ajax (savepng.php) am pus (simplificat):

Cod: Selectaţi tot

<?php
$rezultat = file_put_contents($file,$dia);
?>
Face fisierul $file (care este JPG) dar nu pune nimic in el. Daca pun alert(msg) in success: imi apare un sir foarte lung (codul binar al fisierului). Cum rezolv? Multumesc.

MarPlo Mesaje:4343
Salut
Datele pentru imaginea de canvas sunt preluate de toDataURL() in format base64, In php se preia datele imaginii si se decodeaza cu base64_decode().
- Imaginea de canvas e bine sa fie salvata de php in format PNG; in JPG apare negru partea nedesenata.
Vezi daca iti e de folos acest script.
- html /js code:

Cod: Selectaţi tot

<canvas id="cnv1" width="400" height="280"></canvas>
<button id="btn_cnvimg">Save Canvas Image</button>
<div id="ajaxresp">Ajax response</div>
<script>
var cnv = document.getElementById('cnv1');  //canvas element, with id="cnv1"
var php_file ='save_cnvimg.php';  //address of php file that get and save image on server

/* Ajax Function
 Send "data" to "php", using the method added to "via", and pass response to "callback" function
 data - object with data to send, name:value; ex.: {"name1":"val1", "name2":"2"}
 php - address of the php file where data is send
 via - request method, a string: 'post', or 'get'
 callback - function called to proccess the server response
*/
function ajaxSend(data, php, via, callback) {
  var ob_ajax =  (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');  //XMLHttpRequest object

  //put data from 'data' into a string to be send to 'php'
  var str_data ='';
  for(var k in data) {
    str_data += k +'='+ data[k].replace(/\?/g, '%3F').replace(/=/g, '%3D').replace(/&/g, '%26').replace(/[ ]+/g, '%20') +'&'
  }
  str_data = str_data.replace(/&$/, '');  //delete ending &

  //send data to php
  ob_ajax.open(via, php, true);
  if(via =='post') ob_ajax.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  ob_ajax.send(str_data);

  //check the state request, if completed, pass the response to callback function
  ob_ajax.onreadystatechange = function() {
    if (ob_ajax.readyState == 4) callback(ob_ajax.responseText);
  }
}

//register click on #btn_cnvimg to get and save image
var btn_cnvimg = document.getElementById('btn_cnvimg');
if(btn_cnvimg) btn_cnvimg.addEventListener('click', function(e){
  var imgname = window.prompt('Set a name for the image.\n- If you set a name that already exists,\n the image will be replaced with current canvas-image\n\nLeave empty to let the script set an unique name.', '');

  if(imgname !== null){
    //set data that will be send with ajaxSend() to php (base64 PNG image-data of the canvas, and image-name)
    var img_data = {'cnvimg':cnv.toDataURL('image/png', 1.0), 'imgname':imgname};

    //send image-data to php file
    ajaxSend(img_data, php_file, 'post', function(resp){
      //show server response in #ajaxresp, if not exist, alert response
      if(document.getElementById('ajaxresp')) document.getElementById('ajaxresp').innerHTML = resp;
      else alert(resp);
    });
  }
});
</script>

<script>
//Draw some context in canvas (cnv)
var ctx = cnv.getContext('2d');  //canvas context
ctx.font = 'bold 28px sans-serif';
ctx.strokeText('CANVAS - Save this Image', 46, 50);  //Text
ctx.strokeStyle = '#00f';;
ctx.lineWidth =2;
ctx.arc(200,135,50,0,Math.PI*2,true);  //Face
ctx.moveTo(235,135);
ctx.arc(200,135,35,0,Math.PI,false);  //Mouth
ctx.moveTo(190,125);
ctx.arc(185,125,4,0,Math.PI*2,true);  //Left eye
ctx.moveTo(220,125);
ctx.arc(215,125,4,0,Math.PI*2,true);  //Right eye
ctx.stroke();
</script>
- Fisier save_cnvimg.php :

Cod: Selectaţi tot

<?php
define('UPLOAD_DIR', 'uploads/');  //Upload folder

//get properly base64 image data passed via post in 'cnvimg'
$cnvimg = trim(strip_tags($_POST['cnvimg']));
$cnvimg = str_replace('data:image/png;base64,', '', $cnvimg);
$cnvimg = str_replace(' ', '+', $cnvimg);

//set image name from 'imgname', or unique name set with uniqid()
$imgname = (isset($_POST['imgname']) && !empty(trim($_POST['imgname']))) ? trim(strip_tags($_POST['imgname'])) : uniqid();

//get image data from base64 and save it on server
$data = base64_decode($cnvimg);
$file = UPLOAD_DIR . $imgname .'.png'; 
$success = file_put_contents($file, $data);

//output response (link to image file, or error message)
print $success ? 'Image: <a href="'. $file .'" target="_blank">'. $file .'</a>' : 'Unable to save the file.'; 
Sau poti descarca sctiptul in aceasta arhiva:
Fişiere ataşate
save_canvas_img.zip
(8.86KiB)Descărcat de 307 ori

andras Mesaje:430
Merge brici! Multumesc!
Mai am o problema dar voi reveni cind va functiona serverul developper.

MarPlo Mesaje:4343
Am facut o modificare in script, am adaugat o optiune, un Prompt dialog prin care se poate da un nume pentru imagine inainte de a fi trimisa la server.