Pracuję nad generatywnym projektem artystycznym, w którym chciałbym umożliwić użytkownikom zapisywanie powstałych obrazów z algorytmu. Ogólna idea to:
- Utwórz obraz na kanwie HTML5 przy użyciu algorytmu generatywnego
- Po ukończeniu obrazu zezwól użytkownikom na zapisanie płótna jako pliku obrazu na serwerze
- Pozwól użytkownikowi pobrać obraz lub dodać go do galerii sztuk wyprodukowanych przy użyciu algorytmu.
Utknąłem jednak na drugim etapie. Po pomocy Google znalazłem ten post na blogu , który wydawał się być dokładnie tym, czego chciałem:
Co doprowadziło do kodu JavaScript:
function saveImage() {
var canvasData = canvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.open("POST", "testSave.php", false);
ajax.onreadystatechange = function() {
console.log(ajax.responseText);
}
ajax.setRequestHeader("Content-Type", "application/upload");
ajax.send("imgData=" + canvasData);
}
i odpowiedni PHP (testSave.php):
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
$imageData = $GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData = substr($imageData, strpos($imageData, ",") + 1);
$unencodedData = base64_decode($filteredData);
$fp = fopen('/path/to/file.png', 'wb');
fwrite($fp, $unencodedData);
fclose($fp);
}
?>
Ale to wydaje się w ogóle nic nie robić.
Więcej Googling pokazuje ten post na blogu, który jest oparty na poprzednim samouczku. Nie bardzo różne, ale być może warte spróbowania:
$data = $_POST['imgData'];
$file = "/path/to/file.png";
$uri = substr($data,strpos($data, ",") + 1);
file_put_contents($file, base64_decode($uri));
echo $file;
Ten tworzy plik (tak), ale jest uszkodzony i wydaje się, że nic nie zawiera. Wygląda również na pusty (rozmiar pliku 0).
Czy jest coś naprawdę oczywistego, że robię źle? Ścieżka, w której przechowuję mój plik, jest zapisywalna, więc to nie jest problem, ale wydaje się, że nic się nie dzieje i nie jestem pewien, jak to debugować.
Edytować
Po linku Salvidora Dali zmieniłem żądanie AJAX na:
function saveImage() {
var canvasData = canvas.toDataURL("image/png");
var xmlHttpReq = false;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
ajax.open("POST", "testSave.php", false);
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.onreadystatechange = function() {
console.log(ajax.responseText);
}
ajax.send("imgData=" + canvasData);
}
A teraz plik obrazu został utworzony i nie jest pusty! Wygląda na to, że typ zawartości ma znaczenie i że zmiana go w celu x-www-form-urlencoded
umożliwienia wysłania danych obrazu.
Konsola zwraca (raczej duży) ciąg kodu base64, a plik danych ma wielkość ~ 140 kB. Jednak nadal nie mogę go otworzyć i wydaje się, że nie jest sformatowany jako obraz.
źródło
ajax.send(canvasData );
którego korzystasz, korzysta z niego podczas korzystania z niegoajax.send("imgData="+canvasData);
. Dlatego$GLOBALS["HTTP_RAW_POST_DATA"]
nie będzie to, czego oczekujesz, prawdopodobnie powinieneś użyć$_POST['imgData']
.$data
w drugim kodzie php), wszystko, co otrzymuję, to pusta linia. Dlaczego miałoby to być? Wydaje się, że być może przesyłane dane nie są poprawne, ale wydaje się, że przesyłam je tak, jak pokazują to przykłady ...DataUriUpload
komponentem. Jest to udokumentowane tutaj i zawiera kilka dodatkowych środków sprawdzania poprawności i egzekwowania bezpieczeństwa.Odpowiedzi:
Oto przykład, jak osiągnąć to, czego potrzebujesz:
1) Narysuj coś (wzięte z samouczka na płótnie )
2) Konwertuj obraz na płótnie do formatu URL (base64)
3) Wyślij go na swój serwer przez Ajax
3) Zapisz base64 na serwerze jako obraz (oto jak to zrobić w PHP , te same pomysły są w każdym języku. Po stronie serwera w PHP można znaleźć tutaj ):
źródło
You send it to your server as an ajax request
czy ta metoda wymaga potwierdzenia użytkownika? Czy mogę cicho wysłać obraz z płótna na serwer?Grałem z tym dwa tygodnie temu, jest to bardzo proste. Jedynym problemem jest to, że wszystkie samouczki mówią tylko o lokalnym zapisywaniu obrazu. Oto jak to zrobiłem:
1) Skonfigurowałem formularz, aby móc użyć metody POST.
2) Po zakończeniu rysowania użytkownik może kliknąć przycisk „Zapisz”.
3) Po kliknięciu przycisku biorę dane obrazu i umieszczam je w ukrytym polu. Następnie przesyłam formularz.
4) Po przesłaniu formularza mam ten mały skrypt php:
źródło
Myślę, że powinieneś przenieść obraz w base64 do obrazu z blobem, ponieważ kiedy używasz obrazu base64, potrzeba dużo linii dziennika lub dużo linii zostanie wysłanych na serwer. W przypadku obiektu blob jest to tylko plik. Możesz użyć tego kodu poniżej:
I kod płótna tutaj:
Następnie możesz używać ajax z Form:
Ten kod używa składni CoffeeScript.
jeśli chcesz użyć javascript, wklej kod do http://js2.coffee
źródło
Wyślij obraz na płótnie do PHP:
Oto skrypt PHP:
photo_upload.php
źródło
Jeśli chcesz zapisać dane pochodzące z
canvas.toDataURL()
funkcji Javascript , musisz przekonwertować spacje na plusy. Jeśli tego nie zrobisz, zdekodowane dane są uszkodzone:http://php.net/manual/ro/function.base64-decode.php
źródło
Pracowałem nad czymś podobnym. Musiałem przekonwertować obraz w formacie Canvas w formacie Base64
Uint8Array Blob
.źródło
Oprócz odpowiedzi Salvadora Dali:
po stronie serwera nie zapominaj, że dane są w formacie ciągu base64 . Jest to ważne, ponieważ w niektórych językach programowania musisz wyraźnie powiedzieć, że ten ciąg powinien być traktowany jako bajty, a nie zwykły ciąg Unicode.
W przeciwnym razie dekodowanie nie zadziała: obraz zostanie zapisany, ale będzie to plik nieczytelny.
źródło