নোডজেএস: একটি বেস 64-এনকোডযুক্ত চিত্রটি ডিস্কে সংরক্ষণ করা হচ্ছে


162

আমার এক্সপ্রেস অ্যাপ্লিকেশনটি ব্রাউজার থেকে একটি বেস 64-এনকোডেড পিএনজি গ্রহণ করছে (টুডাআরএল () এর সাথে ক্যানভাস থেকে উত্পন্ন) এবং এটি একটি ফাইলে লিখছে। তবে ফাইলটি কোনও বৈধ চিত্র ফাইল নয় এবং "ফাইল" ইউটিলিটি কেবল এটি "ডেটা" হিসাবে চিহ্নিত করে।

var body = req.rawBody,
  base64Data = body.replace(/^data:image\/png;base64,/,""),
  binaryData = new Buffer(base64Data, 'base64').toString('binary');

require("fs").writeFile("out.png", binaryData, "binary", function(err) {
  console.log(err); // writes out file without error, but it's not a valid image
});

1
আমি উত্তরটি আপডেট করেছি যা আমি মনে করি যা আপনার প্রথম স্থানে প্রয়োজন ছিল;)
আলফ্রেড

স্পষ্টতই এটি আপনি যা চেয়েছিলেন তা নয়, তবে (আমার ক্ষেত্রে) আমি বুঝতে পেরেছিলাম যে সেরা পদ্ধতির সন্ধানটি আমার ডাটাবেসে পুরো এনকোডযুক্ত স্ট্রিংটি সঞ্চয় করা ছিল (আপনি সর্বদা এটি ব্যবহার করে লোড করতে পারেন <img src="data:image/png;base64,..." />)। রেফারেন্স হিসাবে এই থ্রেডটি ব্যবহার করে অন্যদের জন্য বিবেচনা করার জন্য কেবল একটি বিকল্প।
JSideris

উত্তর:


324

আমার মনে হয় আপনি প্রয়োজনের তুলনায় আপনি ডেটা রূপান্তর করছেন। একবার আপনি সঠিক এনকোডিং দিয়ে বাফারটি তৈরি করার পরে আপনাকে কেবল ফাইলটিতে বাফারটি লিখতে হবে।

var base64Data = req.rawBody.replace(/^data:image\/png;base64,/, "");

require("fs").writeFile("out.png", base64Data, 'base64', function(err) {
  console.log(err);
});

নতুন বাফার (..., 'বেস64)' ইনপুট স্ট্রিংটিকে একটি বাফারে রূপান্তরিত করবে, যা ইনপুটটি বেস 64 এনকোডেড স্ট্রিং হিসাবে ব্যাখ্যা করে বাইটের একটি অ্যারে। তারপরে আপনি ফাইলটিতে কেবল বাইট অ্যারে লিখতে পারেন।

হালনাগাদ

মন্তব্যে উল্লিখিত হিসাবে, req.rawBodyএখন আর কোনও জিনিস নয়। আপনি যদি express/ ব্যবহার করে থাকেন connectতবে আপনার bodyParser()মিডলওয়্যারটি ব্যবহার করা উচিত এবং ব্যবহার করা উচিত req.bodyএবং আপনি যদি স্ট্যান্ডার্ড নোড ব্যবহার করে এটি করছেন তবে আপনার আগত dataইভেন্ট Bufferঅবজেক্টগুলিকে একত্রিত করতে হবে এবং endকলব্যাকে এই চিত্রের ডেটা পার্সিং করা উচিত ।


2
এছাড়াও, আপনার উদাহরণে লেখার ফাইলের যুক্তিতে কিছুটা টাইপ রয়েছে: "বাফারডাটা" -> "ডেটাবাফার"।
মাহেমফ

@RJ। req.rawBodyঅনুরোধ ডেটা থাকে যা ডেটা ইউআরএল হিসাবে এনকোড থাকে: ডেভেলপার.মোজিলা.আর.ইন- ইউএস / ডকস / ডেটা_উআরআইএস । সুতরাং সংরক্ষণের জন্য কেবল বেস 64 ডেটা পেতে আপনাকে প্রারম্ভিক অংশটি সরিয়ে ফেলতে হবে।
লগানফস্মিথ

2
এটি দুর্দান্ত জিনিস, ধন্যবাদ! ভবিষ্যতে যাঁরা এটি খুঁজে পান তাদের জন্য, কাঁচাবাডি আর কোনও রেকের সম্পত্তি নয়। ডেটা পেতে আপনাকে এক্সপ্রেস বডি পার্সার মিডলওয়্যার ব্যবহার করতে হবে।
ডিজিটাল ডিজাইনডিজে

10
var base64Data = req.rawBody.split (',') [1];
আনজা mশুখামতোভা

@notgiorgi আপনার সমস্যার পুনরুত্পাদন করার জন্য পর্যাপ্ত বিবরণ সহ একটি নতুন প্রশ্ন জিজ্ঞাসা করার জন্য সেরা, এবং আপনি এটি কাজ করতে পারবেন না বলে এই প্রশ্নের সাথে লিঙ্ক করুন।
লোগানফস্মিথ

22

এটি আমার সম্পূর্ণ সমাধান যা কোনও বেস 64 ইমেজ ফর্ম্যাটটি পড়বে এবং এটি ডাটাবেসে সঠিক বিন্যাসে সংরক্ষণ করবে:

    // Save base64 image to disk
    try
    {
        // Decoding base-64 image
        // Source: http://stackoverflow.com/questions/20267939/nodejs-write-base64-image-file
        function decodeBase64Image(dataString) 
        {
          var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
          var response = {};

          if (matches.length !== 3) 
          {
            return new Error('Invalid input string');
          }

          response.type = matches[1];
          response.data = new Buffer(matches[2], 'base64');

          return response;
        }

        // Regular expression for image type:
        // This regular image extracts the "jpeg" from "image/jpeg"
        var imageTypeRegularExpression      = /\/(.*?)$/;      

        // Generate random string
        var crypto                          = require('crypto');
        var seed                            = crypto.randomBytes(20);
        var uniqueSHA1String                = crypto
                                               .createHash('sha1')
                                                .update(seed)
                                                 .digest('hex');

        var base64Data = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAZABkAAD/4Q3zaHR0cDovL25zLmFkb2JlLmN...';

        var imageBuffer                      = decodeBase64Image(base64Data);
        var userUploadedFeedMessagesLocation = '../img/upload/feed/';

        var uniqueRandomImageName            = 'image-' + uniqueSHA1String;
        // This variable is actually an array which has 5 values,
        // The [1] value is the real image extension
        var imageTypeDetected                = imageBuffer
                                                .type
                                                 .match(imageTypeRegularExpression);

        var userUploadedImagePath            = userUploadedFeedMessagesLocation + 
                                               uniqueRandomImageName +
                                               '.' + 
                                               imageTypeDetected[1];

        // Save decoded binary image to disk
        try
        {
        require('fs').writeFile(userUploadedImagePath, imageBuffer.data,  
                                function() 
                                {
                                  console.log('DEBUG - feed:message: Saved to disk image attached by user:', userUploadedImagePath);
                                });
        }
        catch(error)
        {
            console.log('ERROR:', error);
        }

    }
    catch(error)
    {
        console.log('ERROR:', error);
    }

আমাকে উত্তর দিতে এখানে কেউ আছেন ?? এই সংক্রান্ত??
আইএম

আমি সবেমাত্র আপনার কোড পরিবর্তন করেছি। fs.writeFile ("test.jpg", imageBuffer.data, ফাংশন (ত্রুটি) {json_response ['সাফল্য'] = সত্য; রেজ.জসন (জসন_সত্তর);}); ইমেজ আপলোড করা হয় কিন্তু ফলে হয় না যে আমার কাছে ছন্দ .. ত্রুটি: 502 Bad Gateway এ আসলে res.json সমস্যা, কেন এই মুদ্রণ না হয় ...
IAM

18

হালনাগাদ

আপনার এই পিএইচপি-তে কীভাবে আপনার সমস্যা সমাধান করা যায় আমি এই আকর্ষণীয় লিঙ্কটি পেয়েছি । আমার মনে হয় আপনি প্রতিস্থাপন করতে ভুলে গেছি spaceদ্বারা +হিসাবে লিঙ্কে দেখানো হয়েছে।

আমি এই চেনাশোনাটি http://images-mediawiki-sites.thefullwiki.org/04/1/7/5/6204600836255205.png থেকে নমুনা হিসাবে দেখেছি যা দেখে মনে হচ্ছে:

http://images-mediawiki-sites.thefullwiki.org/04/1/7/5/6204600836255205.png

পরবর্তী আমি এটি http://www.greywyvern.com/code/php/binary2base64 এর মাধ্যমে রেখেছি যা আমাকে ফিরিয়ে দিয়েছে:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAAAAACPAi4CAAAAB3RJTUUH1QEHDxEhOnxCRgAAAAlwSFlzAAAK8AAACvABQqw0mAAAAXBJREFUeNrtV0FywzAIxJ3+K/pZyctKXqamji0htEik9qEHc3JkWC2LRPCS6Zh9HIy/AP4FwKf75iHEr6eU6Mt1WzIOFjFL7IFkYBx3zWBVkkeXAUCXwl1tvz2qdBLfJrzK7ixNUmVdTIAB8PMtxHgAsFNNkoExRKA+HocriOQAiC+1kShhACwSRGAEwPP96zYIoE8Pmph9qEWWKcCWRAfA/mkfJ0F6dSoA8KW3CRhn3ZHcW2is9VOsAgoqHblncAsyaCgcbqpUZQnWoGTcp/AnuwCoOUjhIvCvN59UBeoPZ/AYyLm3cWVAjxhpqREVaP0974iVwH51d4AVNaSC8TRNNYDQEFdlzDW9ob10YlvGQm0mQ+elSpcCCBtDgQD7cDFojdx7NIeHJkqi96cOGNkfZOroZsHtlPYoR7TOp3Vmfa5+49uoSSRyjfvc0A1kLx4KC6sNSeDieD1AWhrJLe0y+uy7b9GjP83l+m68AJ72AwSRPN5g7uwUAAAAAElFTkSuQmCC

এই base64কোডটি আমি আমার কোড থেকে পড়েছি সেভ করে ।

var fs      = require('fs'),
data        = fs.readFileSync('base64', 'utf8'),
base64Data,
binaryData;

base64Data  =   data.replace(/^data:image\/png;base64,/, "");
base64Data  +=  base64Data.replace('+', ' ');
binaryData  =   new Buffer(base64Data, 'base64').toString('binary');

fs.writeFile("out.png", binaryData, "binary", function (err) {
    console.log(err); // writes out file without error, but it's not a valid image
});

আমি একটি বৃত্ত ফিরে পেয়েছি, তবে মজার বিষয় হ'ল ফাইলসাইজ বদলে গেছে:) ...

শেষ

আপনি যখন ব্যাক ইমেজটি পড়বেন তখন আমার মনে হয় আপনার শিরোনাম সেটআপ করা দরকার

উদাহরণস্বরূপ পিএইচপি পৃষ্ঠা থেকে ইমেজপিএনজি নিন :

<?php
$im = imagecreatefrompng("test.png");

header('Content-Type: image/png');

imagepng($im);
imagedestroy($im);
?>

আমি মনে করি দ্বিতীয় লাইনটি header('Content-Type: image/png');গুরুত্বপূর্ণ, অন্যথায় আপনার চিত্রটি ব্রাউজারে প্রদর্শিত হবে না, তবে ব্রাউজারে কেবল একটি গুচ্ছ বাইনারি তথ্য প্রদর্শিত হবে।

ইন এক্সপ্রেস আপনি কেবল শুধু নিচের ভালো কিছু ব্যবহার করেন। আমি আপনার গ্রাভাটারটি প্রদর্শন করতে যাচ্ছি যা http://www.gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG এ অবস্থিত এবং আপনি যখন থাকবেন তখন একটি জেপিগ ফাইল curl --head http://www.gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG। আমি কেবল শিরোনামদের অনুরোধ করছি কারণ অন্যথায় কার্ল কনসোল করতে বাইনারি স্টাফগুলির একটি গুচ্ছ প্রদর্শন করবে (গুগল ক্রোম সাথে সাথে ডাউনলোড করতে যায়):

curl --head "http://www.gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG"
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 03 Aug 2011 12:11:25 GMT
Content-Type: image/jpeg
Connection: keep-alive
Last-Modified: Mon, 04 Oct 2010 11:54:22 GMT
Content-Disposition: inline; filename="cabf735ce7b8b4471ef46ea54f71832d.jpeg"
Access-Control-Allow-Origin: *
Content-Length: 1258
X-Varnish: 2356636561 2352219240
Via: 1.1 varnish
Expires: Wed, 03 Aug 2011 12:16:25 GMT
Cache-Control: max-age=300
Source-Age: 1482

$ mkdir -p ~/tmp/6922728
$ cd ~/tmp/6922728/
$ touch app.js

app.js

var app = require('express').createServer();

app.get('/', function (req, res) {
    res.contentType('image/jpeg');
    res.sendfile('cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG');
});

app.get('/binary', function (req, res) {
    res.sendfile('cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG');
});

app.listen(3000);

$ wget "http://www.gravatar.com/avatar/cabf735ce7b8b4471ef46ea54f71832d?s=32&d=identicon&r=PG"
$ node app.js

ধন্যবাদ আলফ্রেড, তবে এই সর্বনিম্ন পরীক্ষার ক্ষেত্রে, আমি সার্ভার থেকে কোনও কিছুই ফেরত পাঠাচ্ছি না। আমি কেবল সার্ভারে ডিস্কে ফাইলটি লিখছি এবং মনে হচ্ছে ফাইলটি নিজেই কোনও বৈধ চিত্র নয়। আমি বেস 64 মোটামুটি নিশ্চিত, কিন্তু এটি বাইনারি হিসাবে লিখতে সমস্যা দেখা দেয়।
মাহেমফ

1
দুঃখিত আমি প্রশ্নটি ভুল বুঝি: $। আমি আবার চেষ্টা করব.
আলফ্রেড

1
আপডেটের জন্য ধন্যবাদ, তবে স্থানের বিকল্পটি আমার পক্ষে কার্যকর হয়নি এবং আমি লোগানের সমাধানটি প্রয়োগ করার সময় এটি প্রয়োজনীয় ছিল না। রেফারেন্সের জন্য, ক্যানভাসটি আমার পরীক্ষার ক্ষেত্রে খুব সহজ: var প্রসঙ্গ = ক্যানভাস.জেট কনটেক্সট ('2 ডি'); context.fillStyle = "# f89"; context.fillRect (50,50,100,100);
মাহমোফ

ঠিক আছে কারণ আমি যখন এটি করেছি তখন আমি চিত্র ফিরে পেয়েছি তবে কমপক্ষে আপনার সমস্যার সমাধান হয়ে গেছে: পি
অ্যালফ্রেড

আকর্ষণীয়, কেন নিশ্চিত না যে টাস্টস্ট্রিং ("বাইনারি") আপনার ক্ষেত্রে এটিকে গোলমাল করে না। যে কোনও ইভেন্টে ফাঁকা স্থানগুলি স্বাভাবিকভাবেই বেস 64 এ প্রদর্শিত হবে না, সুতরাং প্রতিস্থাপনটি মোটা হওয়া উচিত। এটি আমি যেভাবেই সরবরাহ করেছি উদাহরণ সহ। (আমি ম্যানুয়ালি newোকানো নিউলাইনগুলি সহ একটি বৈকল্পিক চেষ্টা করেছি, এমআইএমআই স্পেক পড়ার পরে lines২ টির বেশি অক্ষরের চেয়ে বেশি লাইন প্রয়োজন হয় না, এটি বেশিরভাগ প্যারাওয়ের বাইরে থাকে ... এটি নতুন লাইনের সাথে বা না ছাড়া কাজ করে , যতক্ষণ না টু স্ট্রিং ("বাইনারি") ) বাদ পড়েছে))
মাহেমফ

6

আমাকে বেস 64৪ টি এনকোড করা চিত্রগুলিও সংরক্ষণ করতে হয়েছিল যা ডেটা ইউআরএলগুলির অংশ, তাই আমি (বা অন্য কেউ) ভবিষ্যতে আবার এটির প্রয়োজন হলে এটি করার জন্য একটি ছোট এনপিএম মডিউল তৈরি করে শেষ করেছি। এটা তোলে বলা হচ্ছে ba64

সহজ কথায় বলতে গেলে এটি বেস 64 এনকোডড চিত্র সহ একটি ডেটা ইউআরএল নেয় এবং আপনার ফাইল সিস্টেমে চিত্রটি সংরক্ষণ করে। এটি সিঙ্ক্রোনালি বা অ্যাসিঙ্ক্রোনালি সংরক্ষণ করতে পারে। এটিতে দুটি সহায়ক ফাংশন রয়েছে, একটি চিত্রের ফাইল এক্সটেনশন পেতে এবং অন্যটি বেস 64 নম্বর এনকোডিংটিকে data:স্কিমের উপসর্গ থেকে পৃথক করে ।

এখানে একটি উদাহরণ:

var ba64 = require("ba64"),
    data_url = "data:image/jpeg;base64,[Base64 encoded image goes here]";

// Save the image synchronously.
ba64.writeImageSync("myimage", data_url); // Saves myimage.jpeg.

// Or save the image asynchronously.
ba64.writeImage("myimage", data_url, function(err){
    if (err) throw err;

    console.log("Image saved successfully");

    // do stuff
});

এটি ইনস্টল করুন : npm i ba64 -S. রেপো গিটহাবে রয়েছে: https://github.com/HarryStevens/ba64

পিএস এটি পরে আমার কাছে এসেছিল যে ba64 সম্ভবত মডিউলটির একটি খারাপ নাম কারণ লোকেরা ধরে নিতে পারে যে এটি বেস 64 এনকোডিং এবং ডিকোডিং করে যা এটি করেন না (ইতিমধ্যে এটি প্রচুর মডিউল রয়েছে)। আচ্ছা ভালো.


2

এটি আমার পক্ষে সহজ এবং নিখুঁতভাবে করেছে।

স্কট রবিনসনের দুর্দান্ত ব্যাখ্যা

ইমেজ থেকে বেস 64 স্ট্রিং

let buff = fs.readFileSync('stack-abuse-logo.png');
let base64data = buff.toString('base64');

বেস 64 স্ট্রিং থেকে চিত্রে

let buff = new Buffer(data, 'base64');
fs.writeFileSync('stack-abuse-logo-out.png', buff);

1

বেস 64 নামক চিত্রটি ফাইলে রূপান্তর করার সহজ উপায় এবং কিছু এলোমেলো আইডি বা নাম সংরক্ষণ করুন।

// to create some random id or name for your image name
const imgname = new Date().getTime().toString();

// to declare some path to store your converted image
const path = yourpath.png    

// image takes from body which you uploaded
const imgdata = req.body.image;    

// to convert base64 format into random filename
const base64Data = imgdata.replace(/^data:([A-Za-z-+/]+);base64,/, '');
fs.writeFile(path, base64Data, 'base64', (err) => {
    console.log(err);
});

// assigning converted image into your database
req.body.coverImage = imgname

1

বেস 6464 স্ট্রিং সহ ফাইলটি পিএনজি চিত্রে রূপান্তর করা হচ্ছে।

4 টি রূপ যা কাজ করে।

var {promisify} = require('util');
var fs = require("fs");

var readFile = promisify(fs.readFile)
var writeFile = promisify(fs.writeFile)

async function run () {

  // variant 1
  var d = await readFile('./1.txt', 'utf8')
  await writeFile("./1.png", d, 'base64')

  // variant 2
  var d = await readFile('./2.txt', 'utf8')
  var dd = new Buffer(d, 'base64')
  await writeFile("./2.png", dd)

  // variant 3
  var d = await readFile('./3.txt')
  await writeFile("./3.png", d.toString('utf8'), 'base64')

  // variant 4
  var d = await readFile('./4.txt')
  var dd = new Buffer(d.toString('utf8'), 'base64')
  await writeFile("./4.png", dd)

}

run();

1

ফাইলগুলি সংরক্ষণ করতে ফাংশনের নীচে, কেবল আপনার বেস64 ফাইলটি পাস করুন, এটি ডিবিতে সংরক্ষণ করে ফাইলের নাম ফিরিয়ে দেয়।

import fs from 'fs';
 const uuid = require('uuid/v1');

/*Download the base64 image in the server and returns the filename and path of image.*/
function saveImage(baseImage) {
    /*path of the folder where your project is saved. (In my case i got it from config file, root path of project).*/
    const uploadPath = "/home/documents/project";
    //path of folder where you want to save the image.
    const localPath = `${uploadPath}/uploads/images/`;
    //Find extension of file
    const ext = baseImage.substring(baseImage.indexOf("/")+1, baseImage.indexOf(";base64"));
    const fileType = baseImage.substring("data:".length,baseImage.indexOf("/"));
    //Forming regex to extract base64 data of file.
    const regex = new RegExp(`^data:${fileType}\/${ext};base64,`, 'gi');
    //Extract base64 data.
    const base64Data = baseImage.replace(regex, "");
    const filename = `${uuid()}.${ext}`;

    //Check that if directory is present or not.
    if(!fs.existsSync(`${uploadPath}/uploads/`)) {
        fs.mkdirSync(`${uploadPath}/uploads/`);
    }
    if (!fs.existsSync(localPath)) {
        fs.mkdirSync(localPath);
    }
    fs.writeFileSync(localPath+filename, base64Data, 'base64');
    return filename;
}

1
আমার জন্য কাজ করেছেন। এবং এটি যে কোনও বেস 64 রূপান্তরগুলির জন্য ব্যবহার করা যেতে পারে। এটি প্রতিটি ফাইলকে উদারভাবে আচরণ করে। ধন্যবাদ!
গিলহের্মে

1

আপনি একটি তৃতীয় পক্ষের লাইব্রেরি যেমন বেস 64-img বা বেস 64-থেকে-চিত্র ব্যবহার করতে পারেন ।

  1. করুন Base64- চিত্র
const base64Img = require('base64-img');

const data = 'data:image/png;base64,...';
const destpath = 'dir/to/save/image';
const filename = 'some-filename';

base64Img.img(data, destpath, filename, (err, filepath) => {}); // Asynchronous using

const filepath = base64Img.imgSync(data, destpath, filename); // Synchronous using
  1. করুন Base64- টু-ইমেজ
const base64ToImage = require('base64-to-image');

const base64Str = 'data:image/png;base64,...';
const path = 'dir/to/save/image/'; // Add trailing slash
const optionalObj = { fileName: 'some-filename', type: 'png' };

const { imageType, fileName } = base64ToImage(base64Str, path, optionalObj); // Only synchronous using
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.