如何从base64数据字符串保存PNG映像服务器端

And*_*iga 198 javascript php base64 html5-canvas

我正在使用Nihilogic的"Canvas2Image"JavaScript工具将画布图转换为PNG图像.我现在需要的是使用PHP将这个工具生成的base64字符串转换为服务器上的实际PNG文件.

简而言之,我目前正在做的是使用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
    }
});
Run Code Online (Sandbox Code Playgroud)

此时,"hidden.php"收到一个看起来像数据的数据块:image/png; base64,iVBORw0KGgoAAAANSUhEUgAABE ...

从现在开始,我非常难过.从我读过的内容来看,我认为我应该使用PHP的imagecreatefromstring函数,但我不确定如何从base64编码的字符串中实际创建一个实际的PNG图像并将其存储在我的服务器上.请帮助!

dre*_*010 407

你需要从该字符串中提取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);
Run Code Online (Sandbox Code Playgroud)

作为一个单行:

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

提取,解码和检查错误的有效方法是:

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);
Run Code Online (Sandbox Code Playgroud)


Som*_*Guy 116

试试这个:

file_put_contents('img.png', base64_decode($base64string));
Run Code Online (Sandbox Code Playgroud)

file_put_contents文档

  • 如果你包含`data:image/png; base64,`那么你传递给`base64_decode`的字符串是无效的base64.您只需发送数据,这是drew010的答案所示.这个答案没有什么破坏.你不能在不理解的情况下进行复制和粘贴,并期望它"正常工作". (19认同)
  • 我试过这个,但它包括`data:image/png; base64,`它打破了文件. (4认同)
  • 不适用于问题中提供的示例,该示例不是base64内容,并且首先必须分成几部分(请参阅接受的答案). (4认同)
  • @MichaelCalkins也为我打破了它.drew010的答案似乎是唯一一致的解决方案. (2认同)

Ben*_*Ben 41

我必须用加号替换空格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);
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • 你的行 `$img = str_replace(' ', '+', $img);` 对我帮助很大,谢谢!为什么我之前必须将空格转换为“+”? (3认同)

Vla*_*lik 18

值得一提的是,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);
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个答案,它应该有更多选票,它使用本机功能,没有肮脏的自制数据操作!虽然,对表演有任何想法吗?正如人们所料,它是否比 `preg_replace` + `file_put_contents` 更快? (3认同)
  • @Bonswoar 谢谢。关于您的问题:在我看来,确保您的应用程序没有性能问题的最佳方法是在您的特定情况下衡量其性能(基于环境、预期和允许的文件大小等)。我们可以尝试在这里玩代码并在答案中显示数字,但事实是,对于您的具体情况,它可能带来的危害大于积极的结果。自己确定总是更好的(尤其是当我们谈论应用程序的性能关键部分时)。 (2认同)

小智 11

那么你的解决方案取决于图像是一个jpeg文件.对于我使用的一般解决方案

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


Pol*_*Zen 10

采用@ 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);
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*sai 7

总的顾虑:

$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);
}
Run Code Online (Sandbox Code Playgroud)

http://php.net/manual/en/wrappers.data.php

http://php.net/manual/en/function.mime-content-type.php


PYK*_*PYK 7

PHP已经公平对待base64 -> 文件转换

我用这样的方式完成编码:

$blob=$_POST['blob']; // base64 coming from an url, for example

//Now, let's save the image file:

file_put_contents('myfile.png',file_get_contents($blob));
Run Code Online (Sandbox Code Playgroud)


Pio*_*otr 6

单线性解决方案。

$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]));
Run Code Online (Sandbox Code Playgroud)


gau*_*ini 6

此代码适用于我检查以下代码:

<?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);
?>
Run Code Online (Sandbox Code Playgroud)


san*_*sht 5

基于 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; 
}
Run Code Online (Sandbox Code Playgroud)