बेस 64 डेटा स्ट्रिंग से पीएनजी इमेज सर्वर-साइड को कैसे बचाया जाए


212

मैं कैनवास चित्र को PNG छवियों में बदलने के लिए Nihilogic के "Canvas2Image" जावास्क्रिप्ट टूल का उपयोग कर रहा हूं। अब मुझे उन आधार 64 स्ट्रिंग्स को चालू करने की आवश्यकता है जो यह उपकरण PHP का उपयोग करके सर्वर पर वास्तविक PNG फ़ाइलों में उत्पन्न करता है।

संक्षेप में, जो मैं वर्तमान में कर रहा हूं वह Canvas2Image का उपयोग करके क्लाइंट की ओर से एक फ़ाइल जनरेट करना है, फिर बेस 64-एन्कोडेड डेटा को पुनः प्राप्त करें और इसे 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" एक डेटा ब्लॉक प्राप्त करता है जो डेटा की तरह दिखता है : छवि / png; आधार 64, iVBORw0KGgoAAAANSUhEUgAABE ...

इस बिंदु से, मैं बहुत ज्यादा स्टम्प्ड हूं। मैंने जो पढ़ा है, उससे मुझे विश्वास है कि मैं PHP के इमेजक्रिएटफ्रॉमस्ट्रिंग फ़ंक्शन का उपयोग करने वाला हूं , लेकिन मुझे यकीन नहीं है कि वास्तव में बेस 64-एन्कोडेड स्ट्रिंग से वास्तविक पीएनजी छवि कैसे बनाई जाए और इसे अपने सर्वर पर संग्रहीत किया जाए। कृपया सहायता करें!


आपको इसे पार्स करने की आवश्यकता है। आप वहां से छवि प्रकार निकाल सकते हैं और फिर base64_decode का उपयोग कर सकते हैं और उस स्ट्रिंग को अपनी छवि प्रकार द्वारा फ़ाइल में सहेज सकते हैं
Constantin

@ कॉन्स्टेंटाइन क्या आप अधिक विशिष्ट हो सकते हैं, कृपया?
आंद्रेई ओनिगा

7
$ डेटा = $ _REQUEST ['base64data']; $ छवि = विस्फोट ('बेस 64,', $ डेटा); file_put_contents ('img.png', base64_decode ($ छवि [1]));
कॉन्सटेंटिन

आप स्नैपशॉट से और जब तक आप डेटा भेजते हैं, तब तक आप इसके लिए काम नहीं कर सकते हैं।
इतिर अट्टिया

जवाबों:


437

आपको उस स्ट्रिंग से बेस 64 छवि डेटा निकालने की आवश्यकता है, इसे डीकोड करें और फिर आप इसे डिस्क पर सहेज सकते हैं, आपको जीडी की आवश्यकता नहीं है क्योंकि यह पहले से ही एक पीएनजी है।

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

आपके पास अपने उदाहरण में $ प्रकार हैं। उस मूल्य क्या होना चाहिए?
जॉन

1
@Jon $typeको विस्फोट से एक मान दिया जाता है, यह इस बात पर निर्भर करता है कि यह डेटा है: छवि / jpg या डेटा: छवि / पीएनजी आदि
drew010

मुझे यह त्रुटि मिली: विकृत utf-8 वर्ण संभवतः गलत तरीके से एन्कोड किया गया है मुझे क्या करना चाहिए?
अल्डो

@aldo शायद कोड और विवरण के साथ एक नया प्रश्न पोस्ट करें। केवल उस संदेश के आधार पर और आपके कोड को देखे बिना या यह जानना कि छवि को कैसे इनकोड किया गया है और इसे स्क्रिप्ट में कैसे भेजा जाता है, कहने में बहुत असंभव है।
drew010

120

इसे इस्तेमाल करे:

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

file_put_contents डॉक्स


4
मैंने यह कोशिश की, लेकिन इसमें वह भी शामिल है data:image/png;base64,जो फ़ाइल को तोड़ता है।
माइकल जे। कल्किंस

2
@MichaelCalkins मेरे लिए भी इसे तोड़ता है। drew010 का जवाब एकमात्र समाधान लगता है जो लगातार काम करता है।
डेविड जॉन वेल्श

24
यदि आप data:image/png;base64,तत्कालीन स्ट्रिंग को शामिल कर रहे हैं तो आप base64_decodeवैध आधार नहीं हैं। आपको केवल डेटा भेजने की आवश्यकता है, जो कि ड्रू010 का उत्तर निराशाजनक है। इस जवाब से कुछ भी नहीं टूटा है। आप समझ के बिना कॉपी और पेस्ट नहीं कर सकते हैं और इसे "बस काम" करने की उम्मीद कर सकते हैं।
साइफ्रे

4
प्रश्न में प्रदान किए गए उदाहरण के लिए काम नहीं कर रहा है, जो एक बेस 64 सामग्री नहीं है, और पहले इसे टुकड़ों में विभाजित किया जाना है (स्वीकृत उत्तर देखें)।
बेंजामिन पीटेट

मेरी छवि को सफलतापूर्वक सहेज लिया गया है। लेकिन जब मैं छवि का url लिखता हूं तो मुझे एक खाली छवि दिखाई देती है। मुझे यकीन है कि मेरा dataURL सही है, क्योंकि मैंने परीक्षण किया कि window.open (dataURL) का उपयोग कर। कोरी छवि क्यों?
पार्थो

45

मुझे 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);

उम्मीद है की वो मदद करदे।


1
आपकी लाइन $img = str_replace(' ', '+', $img);ने मुझे बहुत मदद की, धन्यवाद! मुझे पहले "+" स्थान को क्यों बदलना है?
स्वेन

19

यह कहने योग्य है कि चर्चा किए गए विषय को RFC 2397 में दर्ज़ किया गया है - "डेटा" URL योजना ( https://tools.ietf.org/html/rfc2397 )

इस वजह से PHP के पास इस तरह के डेटा को संभालने का एक मूल तरीका है - "डेटा: स्ट्रीम रैपर" ( 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);

2
मुझे यह उत्तर पसंद है, इसमें अधिक वोट होना चाहिए, यह देशी कार्यों का उपयोग कर रहा है, कोई गंदे घर का डेटा हेरफेर नहीं है! हालांकि, प्रदर्शन के बारे में कोई विचार? यह है, के रूप में एक उम्मीद कर सकते हैं, तेजी से preg_replace+ से file_put_contents?
बोनस्वर

1
@Bonswouar धन्यवाद। आपके प्रश्न के बारे में: मेरी राय में यह सुनिश्चित करने का सबसे अच्छा तरीका है कि आपके आवेदन को प्रदर्शन के मुद्दे नहीं मिले हैं, यह आपके विशेष मामले (पर्यावरण, अपेक्षित और अनुमत फ़ाइल आकार और इसी तरह) के आधार पर इसके प्रदर्शन को मापने के लिए होगा। हम यहां कोड के साथ खेलने और उत्तर में संख्या दिखाने की कोशिश कर सकते हैं, लेकिन सच्चाई यह है कि आपके सटीक मामले के लिए यह सकारात्मक परिणाम की तुलना में अधिक नुकसान पहुंचा सकता है। यह हमेशा अपने दम पर सुनिश्चित करने के लिए बेहतर है (खासकर अगर हम ऐप के प्रदर्शन-महत्वपूर्ण भागों की बात कर रहे हैं)।
व्लादिमीर पॉसविस्टेलिक

11

अच्छी तरह से आपके ऊपर का समाधान छवि पर एक jpeg फ़ाइल होने पर निर्भर करता है। एक सामान्य समाधान के लिए मैंने इस्तेमाल किया

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

11

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


5

एक-रैखिक समाधान।

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

5

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

4

इसे इस्तेमाल करे...

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

4

यह कोड मेरे लिए कोड के नीचे काम करता है:

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

0

यह कार्य करना चाहिए। इसमें फोटो पैरामीटर है जो बेस 64 स्ट्रिंग रखता है और मौजूदा छवि निर्देशिका के लिए भी पथ रखता है। आपके पास पहले से मौजूद छवि होनी चाहिए जिसे आप नया सहेजते समय अनलिंक करना चाहते हैं।

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

0

यह आसान है :

आइए कल्पना करें कि आप जेएस फ्रेमवर्क, एजैक्स अनुरोध या मोबाइल एप्लिकेशन (क्लाइंट साइड) के भीतर एक फ़ाइल अपलोड करने की कोशिश कर रहे हैं

  1. सबसे पहले आप एक डेटा विशेषता भेजते हैं जिसमें एक बेस 64 एनकोडेड स्ट्रिंग होता है।
  2. सर्वर साइड में आपको इसे डिकोड करना होगा और इसे स्थानीय प्रोजेक्ट फ़ोल्डर में सहेजना होगा।

यहाँ 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));

?>

0

यदि आप छवियों को बेतरतीब ढंग से पुनर्नामित करना चाहते हैं, और डेटाबेस पर दोनों छवि पथ को ब्लॉब के रूप में संग्रहीत करते हैं और फ़ोल्डर पर स्वयं छवि इस समाधान में आपकी मदद करेगी। आपकी वेबसाइट के उपयोगकर्ता जितनी चाहें उतनी छवियां संग्रहीत कर सकते हैं, जबकि सुरक्षा उद्देश्यों के लिए छवियों को बेतरतीब ढंग से बदला जाएगा।

Php कोड

छवि नाम के रूप में उपयोग करने के लिए यादृच्छिक varchars उत्पन्न करें।

function genhash($strlen) {
        $h_len = $len;
        $cstrong = TRUE;
        $sslkey = openssl_random_pseudo_bytes($h_len, $cstrong);
        return bin2hex($sslkey);
}
$randName = genhash(3); 
#You can increase or decrease length of the image name (1, 2, 3 or more).

छवि डेटा एक्सटेंशन और आधार_64 भाग (डेटा के बाद का हिस्सा: छवि / पीएनजी; आधार 64) छवि से प्राप्त करें।

$pos  = strpos($base64_img, ';');
$imgExten = explode('/', substr($base64_img, 0, $pos))[1];
$extens = ['jpg', 'jpe', 'jpeg', 'jfif', 'png', 'bmp', 'dib', 'gif' ];

if(in_array($imgExten, $extens)) {

   $imgNewName = $randName. '.' . $imgExten;
   $filepath = "resources/images/govdoc/".$imgNewName;
   $fileP = fopen($filepath, 'wb');
   $imgCont = explode(',', $base64_img);
   fwrite($fileP, base64_decode($imgCont[1]));
   fclose($fileP);

}

# => $filepath <= This path will be stored as blob type in database.
# base64_decoded images will be written in folder too.

# Please don't forget to up vote if you like my solution. :)

0

PHP में पहले से ही एक उचित उपचार बेस 64 -> फाइल ट्रांसफॉर्मेशन है

मैं इसका उपयोग इस तरह से करने के लिए करता हूं:

$blob=$_POST['blob']; // base64 coming from an url, for example
$blob=file_get_contents($blob);
$fh=fopen("myfile.png",'w'); // be aware, it'll overwrite!
fwrite($fh,$blob);
fclose($fh);
echo '<img src=myfile.png>'; // just for the check
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.