Javascript 如何从 base64 数据字符串保存 PNG 图像服务器端
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11511511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to save a PNG image server-side, from a base64 data string
提问by Andrei Oniga
I'm using Nihilogic's "Canvas2Image" JavaScript tool to convert canvas drawings to PNG images. What I need now is to turn those base64 strings that this tool generates, into actual PNG files on the server, using PHP.
我正在使用 Nihilogic 的“Canvas2Image”JavaScript 工具将画布绘图转换为 PNG 图像。我现在需要的是使用 PHP 将这个工具生成的那些 base64 字符串转换为服务器上的实际 PNG 文件。
In short, what I'm currently doing is to generate a file on the client side using Canvas2Image, then retrieve the base64-encoded data and send it to the server using AJAX:
简而言之,我目前正在做的是在客户端使用 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
}
});
At this point, "hidden.php" receives a data block that looks like data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABE...
此时,“hidden.php”接收到一个数据块,看起来像data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABE...
From this point on, I'm pretty much stumped. From what I've read, I believe that I'm supposed to use PHP's imagecreatefromstringfunction, but I'm not sure how to actually create an actual PNG image from the base64-encoded string and store it on my server. Please aid!
从这一点来看,我几乎被难住了。从我读过的内容来看,我相信我应该使用 PHP 的imagecreatefromstring函数,但我不确定如何从 base64 编码的字符串实际创建实际的 PNG 图像并将其存储在我的服务器上。请帮助!
回答by drew010
You need to extract the base64 image data from that string, decode it and then you can save it to disk, you don't need GD since it already is a png.
您需要从该字符串中提取 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);
And as a one-liner:
作为单线:
$data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
An efficient method for extracting, decoding, and checking for errors is:
提取、解码和检查错误的有效方法是:
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);
回答by Some Guy
Try this:
尝试这个:
file_put_contents('img.png', base64_decode($base64string));
回答by Ben
I had to replace spaces with plus symbols str_replace(' ', '+', $img);
to get this working.
我不得不用加号替换空格str_replace(' ', '+', $img);
才能使其正常工作。
Here is the full code
这是完整的代码
$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);
Hope that helps.
希望有帮助。
回答by Vladimir Posvistelik
It worth to say that discussed topic is documented in RFC 2397 - The "data" URL scheme (https://tools.ietf.org/html/rfc2397)
值得一提的是,讨论的主题记录在 RFC 2397 - “数据” URL 方案(https://tools.ietf.org/html/rfc2397)
Because of this PHP has a native way to handle such data - "data: stream wrapper" (http://php.net/manual/en/wrappers.data.php)
因此,PHP 有一种本地方式来处理此类数据 - “数据:流包装器”(http://php.net/manual/en/wrappers.data.php)
So you can easily manipulate your data with PHP streams:
因此,您可以使用 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);
回答by PolloZen
Taken the @dre010 idea, I have extended it to another function that works with any image type: PNG, JPG, JPEG or GIF and gives a unique name to the filename
采用@dre010 的想法,我将它扩展到另一个适用于任何图像类型的函数:PNG、JPG、JPEG 或 GIF,并为文件名提供唯一名称
The function separate image data and image type
该函数将图像数据和图像类型分开
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);
}
回答by devil_io
Well your solution above depends on the image being a jpeg file. For a general solution i used
那么你上面的解决方案取决于图像是一个 jpeg 文件。对于我使用的一般解决方案
$img = $_POST['image'];
$img = substr(explode(";",$img)[1], 7);
file_put_contents('img.png', base64_decode($img));
回答by Nick Tsai
Total concerns:
总的顾虑:
$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);
}
回答by sanjeet bisht
based on drew010 example I made a working example for easy understanding.
基于 draw010 示例,我制作了一个易于理解的工作示例。
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;
}
回答by Piotr
One-linear solution.
单线性解决方案。
$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]));
回答by gauravbhai daxini
This code works for me check below code:
此代码适用于我检查以下代码:
<?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);
?>