Как сохранить изображение 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
}
});
в этот момент, " скрыто.php " получает блок данных это выглядит как данные: изображение / png; base64, iVBORw0KGgoAAAANSUhEUgAABE...
С этого момента я в значительной степени в тупике. Из того, что я прочитал, я считаю, что я должен использовать PHP imagecreatefromstring функция, но я не уверен, как на самом деле создать фактическое изображение PNG из строки с кодировкой base64 и сохранить его на моем сервере.
Пожалуйста, помогите!
12 ответов:
вам нужно извлечь данные изображения 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);
мне пришлось заменить пробелы символами плюс
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);надеюсь, что это поможет.
стоит сказать, что обсуждаемая тема задокументирована в RFC 2397-схема URL" data " (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);
взяв идею @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));
попробуйте это...
$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]));
общая озабоченность:
$data = 'data:image/png;base64,AAAFBfj42Pj4'; // Extract base64 file for standard data $fileBin = file_get_contents($data); $mimeType = mime_content_type($data); // Check allowed mime type if ('image/png'==$mimeType) { file_put_contents('name.png', $fileBin); }
этот код работает для меня, проверьте ниже код:
<?php define('UPLOAD_DIR', 'images/'); $image_parts = explode(";base64,", $_POST['image']); $image_type_aux = explode("image/", $image_parts[0]); $image_type = $image_type_aux[1]; $image_base64 = base64_decode($image_parts[1]); $file = UPLOAD_DIR . uniqid() . '.png'; file_put_contents($file, $image_base64); ?>
на основе примера drew010 я сделал рабочий пример для легкого понимания.
imagesaver("data:image/jpeg;base64,/9j/4AAQSkZJ"); //use full base64 data function imagesaver($image_data){ list($type, $data) = explode(';', $image_data); // exploding data for later checking and validating if (preg_match('/^data:image\/(\w+);base64,/', $image_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'); } $fullname = time().$type; if(file_put_contents($fullname, $data)){ $result = $fullname; }else{ $result = "error"; } /* it will return image name if image is saved successfully or it will return error on failing to save image. */ return $result; }
эта функция должна работать. это имеет параметр photo, который содержит строку base64, а также путь к существующему каталогу изображений, Если у вас уже есть существующее изображение, которое вы хотите отключить при сохранении нового.
public function convertBase64ToImage($photo = null, $path = null) { if (!empty($photo)) { $photo = str_replace('data:image/png;base64,', '', $photo); $photo = str_replace(' ', '+', $photo); $photo = str_replace('data:image/jpeg;base64,', '', $photo); $photo = str_replace('data:image/gif;base64,', '', $photo); $entry = base64_decode($photo); $image = imagecreatefromstring($entry); $fileName = time() . ".jpeg"; $directory = "uploads/customer/" . $fileName; header('Content-type:image/jpeg'); if (!empty($path)) { if (file_exists($path)) { unlink($path); } } $saveImage = imagejpeg($image, $directory); imagedestroy($image); if ($saveImage) { return $fileName; } else { return false; // image not saved } } }
Comments