58

I have a base64 encoded image returned from a service and it looks like this:

/9j/4AAQSkZJRgABAQEASABIAAD/4Yp2aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA0LjEtYzAzNiA0Ni4yNzcwOTIsIEZyaSBGZWIgMjMgMjAwNyAxNDoxNjoxOCAgICAgICAgIj4KICAgPHJkZjpSREYgeG1.... etc

How can i detect / check the image extension?

itsme
  • 48,972
  • 96
  • 224
  • 345
  • this is the image code or image picName/url+picName in base64? – Mark Jan 11 '15 at 12:17
  • ok, is the image code, I can obly get this: ÿØÿà JFIF H H ÿáŠvhttp://ns.adobe.com/xap/1.0/ – Mark Jan 11 '15 at 12:22
  • this is the base64 of the image content, you can get the same encoding an image on this site for example http://www.base64-image.de – itsme Jan 11 '15 at 13:17

10 Answers10

116

A bit late but it seem the question was misunderstood. He just only had the base64 content of the image, not the full data URI.

I wrote here for anyone who encounters with this quest, you can read the first character of content content.charAt(0). By base64 image content if the first char is:

'/' : jpg

'i' : png

'R' : gif

'U' : webp

So for your case, it is 'jpg'.

Fdebijl
  • 887
  • 5
  • 20
Up209d
  • 4,364
  • 4
  • 13
  • 10
36

Was just tweaking with the string. May be this could help.

base64Data.substring("data:image/".length, base64Data.indexOf(";base64"))
Pang
  • 9,564
  • 146
  • 81
  • 122
Saptarshi
  • 603
  • 2
  • 7
  • 15
32

You could also do it with a function chain.

const type = base64Data.split(';')[0].split('/')[1];
Miguel Coder
  • 1,896
  • 19
  • 36
15

For a String (which you can parse out of an image) you can do this:

// Create Base64 Object
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}

// Define the string, also meaning that you need to know the file extension
var encoded = "Base64 encoded image returned from your service";

// Decode the string
var decoded = Base64.decode(encoded);
console.log(decoded);

// if the file extension is unknown
var extension = undefined;
// do something like this
var lowerCase = decoded.toLowerCase();
if (lowerCase.indexOf("png") !== -1) extension = "png"
else if (lowerCase.indexOf("jpg") !== -1 || lowerCase.indexOf("jpeg") !== -1)
    extension = "jpg"
else extension = "tiff";

// and then to display the image
var img = document.createElement("img");
img.src = decoded;

// alternatively, you can do this
img.src = "data:image/" + extension + ";base64," + encoded;

For completion's sake here's the source and I hope this helps!

Tim Visser
  • 916
  • 9
  • 28
  • hi, thank you but i can't understand how to return the original image extension – itsme Jan 11 '15 at 13:26
  • @sbaaaang If you have decoded your payload, i.e. have decoded the Base64 String that the server returned, you have an image like any other. The only difference is, is that you only have the data in your image. In other words the image isn't stored locally, only programmatically. – Tim Visser Jan 11 '15 at 13:38
  • yes but how do i get then the decoded file extension? :D – itsme Jan 11 '15 at 13:53
  • @sbaaaang I have updated my answer. I admit it is a little hacky, but it's the only way to get the file extension with the information the client has. – Tim Visser Jan 11 '15 at 14:24
  • 3
    Why do you define Base64 object, when there are `atob` and `btoa` functions? https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding – Ginden Jan 12 '15 at 21:01
  • this didn't work for me. I ended up having this sort of gibberish on the decoded string: "IDATx^흫r鍆P䒲⊖漍&٠೿R+^ú>Ϙ幧�헿 @䂿┳S4" after decoding my base64 image:"iVBORw0KGgoAAAANSUhEUgAAAfIAAAHyCA..." using the method above – Alejandro Lozdziejski Mar 14 '18 at 16:22
11

A bit late, but you can do it using the file-type module in Node.JS:

npm install file-type

var fileType = require("file-type");

var base64string = "/9j/4AAQSkZJRgABAQEASABIAAD/4Yp2aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA0LjEtYzAzNiA0Ni4yNzcwOTIsIEZyaSBGZWIgMjMgMjAwNyAxNDoxNjoxOCAgICAgICAgIj4KICAgPHJkZjpSREYgeG1";
var base64string_buffer = Buffer.from(base64string, "base64");

(async ()=>{

    var result = await fileType.fromBuffer(base64string_buffer);
    console.log(result);
    //Returns  { ext: 'jpg', mime: 'image/jpeg' }

})();

According to file-type's npm page, it works on getting the magic number which can be found in the returned buffer item. For example, a jpeg starts with ff d8, a pdf with 25 50 44 46, etc.

For reference, here's a snippet from base64string_buffer.toString('hex').match(/../g).join(' '):

ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 48 00 48 00 00 ff e1 8a 76 68 74 74 70 .....

Nicholas Smith
  • 674
  • 1
  • 13
  • 27
8

This one will work for any extension type: pdf, mp3, png, ....

base64.substring(base64.indexOf('/') + 1, base64.indexOf(';base64'));

Pedro Benevides
  • 1,970
  • 18
  • 19
6

By the way you provided invalid Base64 string. correct syntax of base64 encoded image string is like this

"data:image/png;base64,abcdefghijklmnopqrstuvwxyz0123456789......"

You can parse that string and can get the information out of it

const base64str = {profilepic:"data:image/png;base64,abcdefghijklmnopqrstuvwxyz0123456789"};
let mimeType = base64str.profilepic.match(/[^:]\w+\/[\w-+\d.]+(?=;|,)/)[0];

You can see demo here

and if you want to get only extensions you can use following code to get that one. using regex to parse base64 string and get the extension.

const body2 = {profilepic:"data:image/png;base64,abcdefghijklmnopqrstuvwxyz0123456789"};
let mimeType2 = body2.profilepic.match(/[^:/]\w+(?=;|,)/)[0];

check online working Demo here

Muhammad Tahir
  • 2,351
  • 29
  • 25
  • Simple not complicated and it works, how many times would you have a string like the OPs in a real production enviroment. I just needed the extention i used your option two. – Marcos J.D Junior Jan 25 '20 at 16:35
6

use my js function ! it can check JPG,PNG,BMP and so on.

/**
 * @author PiaoZhenJia
 */
function base64FileHeaderMapper(fileBase64) {

    let fileHeader = new Map();

    //get the first 3 char of base64
    fileHeader.set("/9j", "JPG")
    fileHeader.set("iVB", "PNG")
    fileHeader.set("Qk0", "BMP")
    fileHeader.set("SUk", "TIFF")
    fileHeader.set("JVB", "PDF")
    fileHeader.set("UEs", "OFD")

    let res = ""

    fileHeader.forEach((v, k) => {
        if (k == fileBase64.substr(0, 3)) {
            res = v
        }
    })

    //if file is not supported
    if (res == "") {
        res = "unknown file"
    }

    //return map value
    return res;
}
zhenjia piao
  • 61
  • 1
  • 1
1

This one Worked for me perfectly. It will return file type in format 'image/png'

    function base64MimeType(encoded) {
      var result = null;
    
      if (typeof encoded !== 'string') {
        return result;
      }
    
      var mime = encoded.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/);
    
      if (mime && mime.length) {
        result = mime[1];
      }
    
      return result;
    }
sarfrazanwar
  • 373
  • 5
  • 16
0

The above function always returns null

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 16 '23 at 07:22