我正在使用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
    }
});

在这一点上,"idden.php"接收到一个看起来像data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABE...%的数据挡路

从现在起,我几乎被难住了.从我所读到的内容来看,我相信我应该使用PHP的imagecreatefromstring函数,但我不确定如何从base64编码的字符串中创建一个实际的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);

作为一个班轮:

$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 = str_replace( ' ', '+', $data );
    $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);

Javascript相关问答推荐

如何在 javascript 中制作响应式 WASD 控制器

如何将主 js 文件中的数组用于不同的 js 文件?

使用 HTML、CSS 和 JavaScript 在页面刷新时保持选定的主题

如何在不重新渲染未删除的项目的情况下从列表中删除项目?

React 审核表单在提交时未提交审核

使用 jquery-confirm 确认框停止回发,似乎无法获得返回值(webform 项目)

如何根据另一个输入的值进行输入?

JavaScript:具有多个元素的 OnClick 在此关键字下返回“窗口”

'addEventListener' 和 'onclick' 仅适用于 'window' 元素,而不适用于任何其他元素(例如按钮)

在 Javascript 中,(动态)导入的 ES6-Module 实例的类型/类是什么?

React Antd:如何删除垂直分隔线与其旁边的任何内容之间的间距?

使用 JavaScript/React 过滤 API 响应

使用 NextJS 确保敏感代码仅在服务器端运行,这些代码可以从哪里运行?

严格模式与 React 18 的工作方式不同吗?

在自定义钩子中创建一个数组是在每次状态更改时重新渲染值

在两个不同的网页之间共享 HTML 表单数据

受控形式:如果输入无效,则显示 div

在 map Typescript 中添加额外的属性类型

为什么 X === (A || B || C) 什么都不匹配?

遵循 github 上的安装文档后,Flickity-fade 滑块不起作用; flickity 就像普通滑块一样运行