私は、Nihilogicの "Canvas2Image" JavaScriptツールを使ってキャンバス図面をPNG画像に変換します。今必要なのは、このツールが生成するbase64文字列を、PHPを使用してサーバー上の実際の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
}
});
この時点で、 "hidden.php"はdataのようなデータブロックを受け取ります:image/png; base64、iVBORw0KGgoAAAANSUhEUgAABE ...
この時点から、私はほとんど困惑しています。私が読んだものから、私はPHPのimagecreatefromstring関数を使用することになっていると思いますが、base64エンコード文字列から実際のPNG画像を実際に作成する方法はわかりません。それを私のサーバーに保存します。助けてください!
あなたはその文字列からbase64イメージデータを抽出し、それをデコードし、そしてそれをディスクに保存することができる必要があります。それはすでにpngなのでGdは必要ありません。
$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スキーム( 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));
総合的な懸念:
$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);
}
一線形解.
$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]));
これを試して...
$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));
このコードは私のためにうまくいきます。
<?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;
}
この機能は動作するはずです。これは、base64文字列を保持するphotoパラメータと、新しい画像を保存するときにリンク解除する既存の画像がすでにある場合は、既存の画像ディレクトリへのパスも保持します。
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
}
}
}
それは簡単です :
あなたがjsフレームワーク、ajaxリクエスト、またはモバイルアプリケーション(クライアント側)内でファイルをアップロードしようとしていると想像してみましょう。
ここでPHPを使用してそれを行う方法
<?php
$base64String = "kfezyufgzefhzefjizjfzfzefzefhuze"; // I put a static base64 string, you can implement you special code to retrieve the data received via the request.
$filePath = "/MyProject/public/uploads/img/test.png";
file_put_contents($filePath, base64_decode($base64String));
?>