IT story

base64 데이터 문자열에서 PNG 이미지 서버 측을 저장하는 방법

hot-time 2020. 5. 11. 08:04
반응형

base64 데이터 문자열에서 PNG 이미지 서버 측을 저장하는 방법


캔버스 그림을 PNG 이미지로 변환하기 위해 Nihilogic의 "Canvas2Image"JavaScript 도구를 사용하고 있습니다. 내가 지금 필요한 것은 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
    }
});

이 시점에서 "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);

이 시도:

file_put_contents('img.png', base64_decode($base64string));

file_put_contents 문서


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);

희망이 도움이됩니다.


It worth to say that discussed topic is documented in RFC 2397 - The "data" URL scheme (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)

So you can easily manipulate your data with PHP streams:

$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);

Well your solution above depends on the image being a jpeg file. For a general solution i used

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

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

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);
}

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]));

based on drew010 example I made a working example for easy understanding.

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; 
}

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);
}

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

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


try this...

$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));

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);
?>

This function should work. this has the photo parameter that holds the base64 string and also path to an existing image directory should you already have an existing image you want to unlink while you save the new one.

 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
        }
    }
}

It's simple :

Let's imagine that you are trying to upload a file within js framework, ajax request or mobile application (Client side)

  1. Firstly you send a data attribute that contains a base64 encoded string.
  2. In the server side you have to decode it and save it in a local project folder.

Here how to do it using 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));

?>

참고URL : https://stackoverflow.com/questions/11511511/how-to-save-a-png-image-server-side-from-a-base64-data-string

반응형