Как сохранить PNG-изображение на стороне сервера, из строки данных base64

Я использую инструмент JavaScript «Canvas2Image» от Nihilogic для преобразования рисунков холста в изображения PNG. Теперь мне нужно превратить те строки base64, которые этот инструмент генерирует, в фактические файлы PNG на сервере, используя PHP.

Короче говоря, то, что я сейчас делаю, – это сгенерировать файл на стороне клиента с помощью Canvas2Image, а затем получить данные, закодированные в base64, и отправить их на сервер с помощью AJAX:

// Generate the image file var image = Canvas2Image.saveAsPNG(canvas, true); image.id = "canvasimage"; canvas.parentNode.replaceChild(image, canvas); var url = 'hidden.php', data = $('#canvasimage').attr('src'); $.ajax({ type: "POST", url: url, dataType: 'text', data: { base64data : data } }); 

На данный момент «hidden.php» получает блок данных, который выглядит как данные: image / png; base64, iVBORw0KGgoAAAANSUhEUgAABE …

С этого момента я очень сильно тупой. Из того, что я читал, я считаю, что я должен использовать функцию imagecreatefromstring PHP, но я не уверен, как создать реальное изображение PNG из кодированной base64 строки и сохранить его на моем сервере. Пожалуйста, помогите!

Вам нужно извлечь данные изображения base64 из этой строки, декодировать его, а затем вы можете сохранить его на диск, вам не нужен GD, поскольку он уже является png.

 $data = 'data:image/png;base64,AAAFBfj42Pj4'; list($type, $data) = explode(';', $data); list(, $data) = explode(',', $data); $data = base64_decode($data); file_put_contents('/tmp/image.png', $data); 

И как однострочный:

 $data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data)); 

Эффективным методом для извлечения, декодирования и проверки ошибок является:

 if (preg_match('/^data:image\/(\w+);base64,/', $data, $type)) { $data = substr($data, strpos($data, ',') + 1); $type = strtolower($type[1]); // jpg, png, gif if (!in_array($type, [ 'jpg', 'jpeg', 'gif', 'png' ])) { throw new \Exception('invalid image type'); } $data = base64_decode($data); if ($data === false) { throw new \Exception('base64_decode failed'); } } else { throw new \Exception('did not match data URI with image data'); } file_put_contents("img.{$type}", $data); 

Попробуй это:

 file_put_contents('img.png', base64_decode($base64string)); 

Документы file_put_contents

Мне пришлось заменить пробелы плюс символами str_replace(' ', '+', $img); чтобы это работало.

Вот полный код

 $img = $_POST['img']; // Your data 'data:image/png;base64,AAAFBfj42Pj4'; $img = str_replace('data:image/png;base64,', '', $img); $img = str_replace(' ', '+', $img); $data = base64_decode($img); file_put_contents('/tmp/image.png', $data); 

Надеюсь, это поможет.

Взяв идею @ dre010, я распространил ее на другую функцию, которая работает с любым типом изображения: PNG, JPG, JPEG или GIF и дает уникальное имя файлу

Функция разделяет данные изображения и тип изображения

 function base64ToImage($imageData){ $data = 'data:image/png;base64,AAAFBfj42Pj4'; list($type, $imageData) = explode(';', $imageData); list(,$extension) = explode('/',$type); list(,$imageData) = explode(',', $imageData); $fileName = uniqid().'.'.$extension; $imageData = base64_decode($imageData); file_put_contents($fileName, $imageData); } 

Ну, ваше решение выше зависит от того, как изображение является файлом jpeg. Для общего решения, которое я использовал

 $img = $_POST['image']; $img = substr(explode(";",$img)[1], 7); file_put_contents('img.png', base64_decode($img)); 

Стоит сказать, что обсуждаемая тема документирована в RFC 2397 – Схема URL-адресов данных ( https://tools.ietf.org/html/rfc2397 )

Из-за этого PHP имеет собственный способ обработки таких данных – «data: stream wrapper» ( http://php.net/manual/en/wrappers.data.php )

Таким образом, вы можете легко манипулировать своими данными потоками PHP:

 $data = 'data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7'; $source = fopen($data, 'r'); $destination = fopen('image.gif', 'w'); stream_copy_to_stream($source, $destination); fclose($source); fclose($destination); 

попробуй это…

 $file = $_POST['file']; //your data in base64 'data:image/png....'; $img = str_replace('data:image/png;base64,', '', $file); file_put_contents('img/imag.png', base64_decode($img)); 

Однолинейное решение.

 $base64string = 'data:image/png;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7'; file_put_contents('img.png', base64_decode(explode(',',$base64string)[1]));