2011-07-18 15 views
45

Mam identyfikator URI danych otrzymuję od javascript i próbuję zapisać przez php. Używam następującego kodu, który daje pozornie uszkodzony plik obrazu:PHP Data-URI do pliku

$data = $_POST['logoImage']; 

    $uri = substr($data,strpos($data,",")+1); 

    file_put_contents($_POST['logoFilename'], base64_decode($uri)); 



data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs 9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAxklEQVQYlYWQMW7CUBBE33yITYUUmwbOkBtEcgUlTa7COXIVV5RUkXKC5AxU EdyZVD4kyKxkwIrr9vd0c7Oih aopinLNsF6Qkg2XW4XJ7LGFsAAcTV6lF5/jLdbALA9XDAXYfthFQVx OrmqKYK88/7rbbMFksALieTnzu9wDYTj6f70PKsp2kwAiSvjXNcvkWpAfNZkzWa/5a9yT7fdoX7rrB7hYh2fXo9HdjPYQZu3MIU8bYIlW20y0RUlXG2Kpv/vfwLxhTaSQwWqwhAAAAAElFTkSuQmCC 

Poniżej kodu znajduje się rzeczywisty obraz jako URI danych. "logoImage" to powyższy łańcuch, a $ uri to ciąg minus "image/jpeg; base64".

+0

Przepraszam ja zrobić literówkę gdzieś? – GAgnew

+0

Identyfikator URI danych w twoim przykładzie nie jest prawidłowym obrazem PNG. To nigdy nie zadziała i nie ma związku z kodem, jest powiązane z danymi. – hakre

+0

Możesz chcieć zachować to jako obraz base64. Zgaduję, ponieważ nie jestem ekspertem binarnym, że wszystkie podane tu przykłady dają wynik 32-bitowy. Począwszy od PHP 5.2, adresy URL danych powinny działać, więc rozwiązanie może być tak proste jak: 'file_put_contents ('logo.png', preg_replace (/ \ s + /, '+', $ _POST ['logoImage']))' jeśli używasz JavaScript FileReader API w połączeniu z AJAX. – PHPglue

Odpowiedz

61

Szybkie spojrzenie at the PHP manual daje następujące:

Jeśli chcesz zapisać dane, które pochodzi od funkcji JavaScript canvas.toDataURL(), trzeba przekonwertować półwyrobów do plusses. Jeśli nie zrobisz, dekodowane dane są uszkodzone:

<?php 
    $encodedData = str_replace(' ','+',$encodedData); 
    $decodedData = base64_decode($encodedData); 
?> 
+0

To działało. Wow, nie mogę uwierzyć, że nie mogłem tego wcześniej znaleźć! Przyjmę to tak szybko, jak tylko będę mógł, dzięki @Graydot – GAgnew

40

Dane identyfikatora URI, które masz w swoim przykładzie, nie są poprawnym obrazem PNG. To nigdy nie zadziała i nie ma związku z kodem, jest powiązane z danymi.


nie ma zastosowania, ale może być interesujące:

file_put_contents($_POST['logoFilename'], file_get_contents($data)); 

Ideą: Samo PHP może odczytać zawartość data URIs (data://), dzięki czemu nie trzeba dekodować go na własną rękę.

Należy pamiętać, że oficjalny schemat URI danych (nr ref .: The "data" URL scheme RFC 2397) nie zawiera podwójnego ukośnika ("//") po dwukropku (":"). PHP obsługuje z dwoma ukośnikami lub bez nich.

# RFC 2397 conform 
$binary = file_get_contents($uri); 

# with two slashes 
$uriPhp = 'data://' . substr($uri, 5); 
$binary = file_get_contents($uriPhp); 
+2

I wreszcie: 'file_put_contents ($ _ POST ['logoFilename'], $ binary);' – andreszs

+0

Jesteśmy na PHP 5.5.25 i wydaje się, że nie ma potrzeby dodawania podwójnych ukośników. – Andz

+1

@Andz: Wygląda na to, że w PHP 5.2+ to zawsze działało: http://3v4l.org/Fk4RY - bardzo fajny Komentarz do PHP.net też ma lata. Nie ufaj mapie, zaufaj terenowi, jeszcze raz dzięki za podpowiedź. Poprawiono odpowiedź. – hakre

19

Cały kod, który działa:

$imgData = str_replace(' ','+',$_POST['image']); 
$imgData = substr($imgData,strpos($imgData,",")+1); 
$imgData = base64_decode($imgData); 
// Path where the image is going to be saved 
$filePath = $_SERVER['DOCUMENT_ROOT']. '/ima/temp2.png'; 
// Write $imgData into the image file 
$file = fopen($filePath, 'w'); 
fwrite($file, $imgData); 
fclose($file); 
+0

!! – Jake